Merge remote-tracking branch 'upstream/master' into snmp-autoreduce

This commit is contained in:
garnier-quentin 2018-12-30 23:05:48 +01:00
commit 538fe8c269
47 changed files with 4360 additions and 78 deletions

View File

@ -0,0 +1,132 @@
#
# 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 centreon::common::fortinet::fortigate::mode::vdomcpu;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub prefix_vdom_output {
my ($self, %options) = @_;
return "Virtual domain '" . $options{instance_value}->{fgVdEntName} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'vdoms', type => 1, cb_prefix_output => 'prefix_vdom_output', message_multiple => 'All cpu usage are ok' },
];
$self->{maps_counters}->{vdoms} = [
{ label => 'usage', set => {
key_values => [ { name => 'fgVdEntCpuUsage' }, { name => 'fgVdEntName' } ],
output_template => 'CPU usage: %.2f%%',
perfdatas => [
{ label => 'cpu_usage', value => 'fgVdEntCpuUsage_absolute', template => '%.2f',
min => 0, min => 100, unit => '%', label_extra_instance => 1, instance_use => 'fgVdEntName_absolute' },
],
}
},
];
}
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-name:s" => { name => 'filter_name' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
my $mapping = {
fgVdEntName => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.2' },
fgVdEntCpuUsage => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.5' },
};
my $oid_fgVdInfo = '.1.3.6.1.4.1.12356.101.3.2';
sub manage_selection {
my ($self, %options) = @_;
$self->{vdoms} = {};
my $results = $options{snmp}->get_table(oid => $oid_fgVdInfo , nothing_quit => 1);
foreach my $oid (keys %{$results}) {
next if ($oid !~ /^$mapping->{fgVdEntCpuUsage}->{oid}\.(\d+)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{fgVdEntName} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1);
next;
}
$self->{vdoms}->{$result->{fgVdEntName}} = {
fgVdEntName => $result->{fgVdEntName},
fgVdEntCpuUsage => $result->{fgVdEntCpuUsage},
}
}
if (scalar(keys %{$self->{vdoms}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check virtual domains CPU usage.
=over 8
=item B<--filter-name>
Filter by virtual domain name (can be a regexp).
=item B<--warning-usage>
Threshold warning.
=item B<--critical-usage>
Threshold critical.
=back
=cut

View File

@ -0,0 +1,132 @@
#
# 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 centreon::common::fortinet::fortigate::mode::vdommemory;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub prefix_vdom_output {
my ($self, %options) = @_;
return "Virtual domain '" . $options{instance_value}->{fgVdEntName} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'vdoms', type => 1, cb_prefix_output => 'prefix_vdom_output', message_multiple => 'All memory usage are ok' },
];
$self->{maps_counters}->{vdoms} = [
{ label => 'usage', set => {
key_values => [ { name => 'fgVdEntMemUsage' }, { name => 'fgVdEntName' } ],
output_template => 'memory usage: %.2f%%',
perfdatas => [
{ label => 'memory_usage', value => 'fgVdEntMemUsage_absolute', template => '%.2f',
min => 0, min => 100, unit => '%', label_extra_instance => 1, instance_use => 'fgVdEntName_absolute' },
],
}
},
];
}
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-name:s" => { name => 'filter_name' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
my $mapping = {
fgVdEntName => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.2' },
fgVdEntMemUsage => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.6' },
};
my $oid_fgVdInfo = '.1.3.6.1.4.1.12356.101.3.2';
sub manage_selection {
my ($self, %options) = @_;
$self->{vdoms} = {};
my $results = $options{snmp}->get_table(oid => $oid_fgVdInfo , nothing_quit => 1);
foreach my $oid (keys %{$results}) {
next if ($oid !~ /^$mapping->{fgVdEntMemUsage}->{oid}\.(\d+)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{fgVdEntName} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1);
next;
}
$self->{vdoms}->{$result->{fgVdEntName}} = {
fgVdEntName => $result->{fgVdEntName},
fgVdEntMemUsage => $result->{fgVdEntMemUsage},
}
}
if (scalar(keys %{$self->{vdoms}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check virtual domains memory usage.
=over 8
=item B<--filter-name>
Filter by virtual domain name (can be a regexp).
=item B<--warning-usage>
Threshold warning.
=item B<--critical-usage>
Threshold critical.
=back
=cut

View File

@ -0,0 +1,145 @@
#
# 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 centreon::common::fortinet::fortigate::mode::vdomsession;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub prefix_vdom_output {
my ($self, %options) = @_;
return "Virtual domain '" . $options{instance_value}->{fgVdEntName} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'vdoms', type => 1, cb_prefix_output => 'prefix_vdom_output', message_multiple => 'All session metrics are ok' },
];
$self->{maps_counters}->{vdoms} = [
{ label => 'active-session', set => {
key_values => [ { name => 'fgVdEntSesCount' }, { name => 'fgVdEntName' } ],
output_template => 'Active sessions: %d',
perfdatas => [
{ label => 'active_sessions', value => 'fgVdEntSesCount_absolute', template => '%d',
min => 0, unit => 'sessions', label_extra_instance => 1, instance_use => 'fgVdEntName_absolute' },
],
}
},
{ label => 'session-rate', set => {
key_values => [ { name => 'fgVdEntSesRate' }, { name => 'fgVdEntName' } ],
output_template => 'Session setup rate: %d sessions/s',
perfdatas => [
{ label => 'session_rate', value => 'fgVdEntSesRate_absolute', template => '%d',
min => 0, unit => 'sessions/s', label_extra_instance => 1, instance_use => 'fgVdEntName_absolute' },
],
}
},
];
}
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-name:s" => { name => 'filter_name' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
my $mapping = {
fgVdEntName => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.2' },
fgVdEntSesCount => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.7' },
fgVdEntSesRate => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.8' },
};
my $oid_fgVdInfo = '.1.3.6.1.4.1.12356.101.3.2';
sub manage_selection {
my ($self, %options) = @_;
$self->{vdoms} = {};
my $results = $options{snmp}->get_table(oid => $oid_fgVdInfo , nothing_quit => 1);
foreach my $oid (keys %{$results}) {
next if ($oid !~ /^$mapping->{fgVdEntSesCount}->{oid}\.(\d+)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{fgVdEntName} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1);
next;
}
$self->{vdoms}->{$result->{fgVdEntName}} = {
fgVdEntName => $result->{fgVdEntName},
fgVdEntSesCount => $result->{fgVdEntSesCount},
fgVdEntSesRate => $result->{fgVdEntSesRate},
}
}
if (scalar(keys %{$self->{vdoms}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check virtual domains active sessions count and session setup rate.
=over 8
=item B<--filter-name>
Filter by virtual domain name (can be a regexp).
=item B<--warning-*>
Threshold warning.
Can be: 'active-session', 'session-rate'.
=item B<--critical-*>
Threshold critical.
Can be: 'active-session', 'session-rate'.
=back
=cut

View File

@ -0,0 +1,202 @@
#
# 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 centreon::common::fortinet::fortigate::mode::vdomstate;
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 = sprintf("Operation mode is '%s', HA cluster member state is '%s'",
$self->{result_values}->{op_mode}, $self->{result_values}->{ha_state});
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{op_mode} = $options{new_datas}->{$self->{instance} . '_fgVdEntOpMode'};
$self->{result_values}->{ha_state} = $options{new_datas}->{$self->{instance} . '_fgVdEntHaState'};
return 0;
}
sub prefix_vdom_output {
my ($self, %options) = @_;
return "Virtual domain '" . $options{instance_value}->{fgVdEntName} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'vdoms', type => 1, cb_prefix_output => 'prefix_vdom_output', message_multiple => 'All states are ok' },
];
$self->{maps_counters}->{vdoms} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'fgVdEntOpMode' }, { name => 'fgVdEntHaState' }, { name => 'fgVdEntName' } ],
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-name:s" => { name => 'filter_name' },
"warning-status:s" => { name => 'warning_status', default => '' },
"critical-status:s" => { name => 'critical_status', default => '' },
});
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);
$self->change_macros();
$instance_mode = $self;
}
my %map_op_mode = (
1 => 'nat',
2 => 'transparent',
);
my %map_ha_state = (
1 => 'master',
2 => 'backup',
3 => 'standalone',
);
my $mapping = {
fgVdEntName => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.2' },
fgVdEntOpMode => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.3', map => \%map_op_mode },
fgVdEntHaState => { oid => '.1.3.6.1.4.1.12356.101.3.2.1.1.4', map => \%map_ha_state },
};
my $oid_fgVdInfo = '.1.3.6.1.4.1.12356.101.3.2';
sub manage_selection {
my ($self, %options) = @_;
$self->{vdoms} = {};
my $results = $options{snmp}->get_table(oid => $oid_fgVdInfo , nothing_quit => 1);
foreach my $oid (keys %{$results}) {
next if ($oid !~ /^$mapping->{fgVdEntHaState}->{oid}\.(\d+)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$result->{fgVdEntName} !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1);
next;
}
$self->{vdoms}->{$result->{fgVdEntName}} = {
fgVdEntName => $result->{fgVdEntName},
fgVdEntOpMode => $result->{fgVdEntOpMode},
fgVdEntHaState => $result->{fgVdEntHaState},
}
}
if (scalar(keys %{$self->{vdoms}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check virtual domains operation mode and HA cluster member state.
=over 8
=item B<--filter-name>
Filter by virtual domain name (can be a regexp).
=item B<--warning-status>
Set warning threshold for status (Default: '').
Can used special variables like: %{op_mode}, %{ha_state}
=item B<--critical-status>
Set critical threshold for status (Default: '').
Can used special variables like: %{op_mode}, %{ha_state}
=back
=cut

View File

@ -0,0 +1,237 @@
#
# 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 centreon::common::fortinet::fortigate::mode::vdomusage;
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 = sprintf("Virtual domains are '%s' on this device", $self->{result_values}->{state});
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_fgVdEnabled'};
return 0;
}
sub custom_usage_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(label => 'used',
value => $self->{result_values}->{used},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1),
min => 0, max => $self->{result_values}->{total});
}
sub custom_usage_threshold {
my ($self, %options) = @_;
my ($exit, $threshold_value);
$threshold_value = $self->{result_values}->{used};
$threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free}));
if ($instance_mode->{option_results}->{units} eq '%') {
$threshold_value = $self->{result_values}->{prct_used};
$threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free}));
}
$exit = $self->{perfdata}->threshold_check(value => $threshold_value,
threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' },
{ label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]);
return $exit;
}
sub custom_usage_output {
my ($self, %options) = @_;
my $msg = sprintf("Number of virtual domains used: %s/%s (%.2f%%)", $self->{result_values}->{used},
$self->{result_values}->{total}, $self->{result_values}->{prct_used});
return $msg;
}
sub custom_usage_calc {
my ($self, %options) = @_;
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_fgVdNumber'};
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_fgVdMaxVdoms'};
$self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used};
$self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total};
$self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used};
return 0;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 },
];
$self->{maps_counters}->{global} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'fgVdEnabled' } ],
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'),
}
},
{ label => 'usage', set => {
key_values => [ { name => 'fgVdNumber' }, { name => 'fgVdMaxVdoms' } ],
closure_custom_calc => $self->can('custom_usage_calc'),
closure_custom_output => $self->can('custom_usage_output'),
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
closure_custom_threshold_check => $self->can('custom_usage_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 => '%{state} eq "disabled"' },
"critical-status:s" => { name => 'critical_status', default => '' },
"units:s" => { name => 'units', default => '%' },
"free" => { name => 'free' },
});
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);
$self->change_macros();
$instance_mode = $self;
}
my %map_state = (
1 => 'disabled',
2 => 'enabled',
);
my $mapping = {
fgVdNumber => { oid => '.1.3.6.1.4.1.12356.101.3.1.1' },
fgVdMaxVdoms => { oid => '.1.3.6.1.4.1.12356.101.3.1.2' },
fgVdEnabled => { oid => '.1.3.6.1.4.1.12356.101.3.1.3', map => \%map_state },
};
my $oid_fgVdInfo = '.1.3.6.1.4.1.12356.101.3.1';
sub manage_selection {
my ($self, %options) = @_;
$self->{global} = {};
$self->{results} = $options{snmp}->get_table(oid => $oid_fgVdInfo , nothing_quit => 1);
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => 0);
$self->{global} = {%{$result}};
}
1;
__END__
=head1 MODE
Check virtual domains activation and slots usage.
=over 8
=item B<--warning-status>
Set warning threshold for status (Default: '%{state} eq "disabled"').
Can used special variables like: %{state}
=item B<--critical-status>
Set critical threshold for status (Default: '').
Can used special variables like: %{state}
=item B<--warning-usage>
Threshold warning.
=item B<--critical-usage>
Threshold critical.
=item B<--units>
Units of thresholds (Default: '%') ('%', 'count').
=item B<--free>
Thresholds are on free virtual domain slots.
=back
=cut

View File

@ -191,6 +191,12 @@ sub is_version_minimum {
return 1;
}
sub set_version {
my ($self) = @_;
$self->{version} = $self->{instance}->get_info(18); # SQL_DBMS_VER
}
sub connect {
my ($self, %options) = @_;
my $dontquit = (defined($options{dontquit}) && $options{dontquit} == 1) ? 1 : 0;
@ -220,7 +226,7 @@ sub connect {
return (-1, $err_msg);
}
$self->{version} = $self->{instance}->get_info(18); # SQL_DBMS_VER
$self->set_version();
return 0;
}
@ -256,18 +262,23 @@ sub fetchrow_hashref {
sub query {
my ($self, %options) = @_;
my $continue_error = defined($options{continue_error}) && $options{continue_error} == 1 ? 1 : 0;
$self->{statement_handle} = $self->{instance}->prepare($options{query});
if (!defined($self->{statement_handle})) {
return 1 if ($continue_error == 1);
$self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{instance}->errstr);
$self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit});
}
my $rv = $self->{statement_handle}->execute;
if (!$rv) {
return 1 if ($continue_error == 1);
$self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{statement_handle}->errstr);
$self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit});
}
return 0;
}
1;

View File

@ -479,7 +479,7 @@ sub get_multiple_table {
my $base = $bases[$pos % $current_oids];
if ($complete_oid !~ /^$base\./ ||
(defined($working_oids->{ $bases[$pos % $current_oids] }->{end}) &&
$self->check_oid_up($complete_oid, $working_oids->{ $bases[$pos % $current_oids] }->{end}) )) {
$self->check_oid_up(current => $complete_oid, end => $working_oids->{ $bases[$pos % $current_oids] }->{end}))) {
delete $working_oids->{ $bases[$pos % $current_oids] };
next;
}
@ -614,7 +614,7 @@ sub get_table {
# Not in same table
my $complete_oid = ${$entry}[0] . "." . ${$entry}[1];
if ($complete_oid !~ /^$main_indice\./ ||
(defined($options{end}) && $self->check_oid_up($complete_oid, $options{end}) )) {
(defined($options{end}) && $self->check_oid_up(current => $complete_oid, end => $options{end}))) {
$leave = 0;
last;
}
@ -689,8 +689,10 @@ sub clean_oid {
}
sub check_oid_up {
my ($self) = @_;
my ($current_oid, $end_oid) = @_;
my ($self, %options) = @_;
my $current_oid = $options{current};
my $end_oid = $options{end};
my @current_oid_splitted = split /\./, $current_oid;
my @end_oid_splitted = split /\./, $end_oid;

View File

@ -312,9 +312,7 @@ sub run_instances {
);
}
if ($self->{multiple_lvl1} == 0 && $multiple_lvl2 == 0 && !$options{multi}) {
$self->{output}->output_add(short_msg => $prefix_output . $long_msg . $suffix_output);
}
$self->{output}->output_add(short_msg => $prefix_output . $long_msg . $suffix_output) unless ($self->{multiple_lvl1} == 1 || ($multiple_lvl2 == 1 && !defined($options{multi})));
if ($options{multi}) {
foreach my $counter (@{$options{config}->{counters}}) {

View File

@ -0,0 +1,415 @@
#
# 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 cloud::microsoft::office365::custom::graphapi;
use strict;
use warnings;
use DateTime;
use centreon::plugins::http;
use centreon::plugins::statefile;
use JSON::XS;
use Text::CSV;
use Encode;
use URI::Encode;
use Digest::MD5 qw(md5_hex);
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
if (!defined($options{output})) {
print "Class Custom: Need to specify 'output' argument.\n";
exit 3;
}
if (!defined($options{options})) {
$options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument.");
$options{output}->option_exit();
}
if (!defined($options{noptions})) {
$options{options}->add_options(arguments =>
{
"tenant:s" => { name => 'tenant' },
"client-id:s" => { name => 'client_id' },
"client-secret:s" => { name => 'client_secret' },
"login-endpoint:s" => { name => 'login_endpoint' },
"graph-endpoint:s" => { name => 'graph_endpoint' },
"timeout:s" => { name => 'timeout' },
"proxyurl:s" => { name => 'proxyurl' },
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{mode} = $options{mode};
$self->{http} = centreon::plugins::http->new(output => $self->{output});
$self->{cache} = centreon::plugins::statefile->new(%options);
return $self;
}
sub set_options {
my ($self, %options) = @_;
$self->{option_results} = $options{option_results};
}
sub set_defaults {
my ($self, %options) = @_;
foreach (keys %{$options{default}}) {
if ($_ eq $self->{mode}) {
for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) {
foreach my $opt (keys %{$options{default}->{$_}[$i]}) {
if (!defined($self->{option_results}->{$opt}[$i])) {
$self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt};
}
}
}
}
}
}
sub check_options {
my ($self, %options) = @_;
$self->{tenant} = (defined($self->{option_results}->{tenant})) ? $self->{option_results}->{tenant} : undef;
$self->{client_id} = (defined($self->{option_results}->{client_id})) ? $self->{option_results}->{client_id} : undef;
$self->{client_secret} = (defined($self->{option_results}->{client_secret})) ? $self->{option_results}->{client_secret} : undef;
$self->{login_endpoint} = (defined($self->{option_results}->{login_endpoint})) ? $self->{option_results}->{login_endpoint} : 'https://login.microsoftonline.com';
$self->{graph_endpoint} = (defined($self->{option_results}->{graph_endpoint})) ? $self->{option_results}->{graph_endpoint} : 'https://graph.microsoft.com';
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10;
$self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef;
$self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef;
if (!defined($self->{tenant}) || $self->{tenant} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --tenant option.");
$self->{output}->option_exit();
}
if (!defined($self->{client_id}) || $self->{client_id} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --client-id option.");
$self->{output}->option_exit();
}
if (!defined($self->{client_secret}) || $self->{client_secret} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --client-secret option.");
$self->{output}->option_exit();
}
$self->{cache}->check_options(option_results => $self->{option_results});
return 0;
}
sub build_options_for_httplib {
my ($self, %options) = @_;
$self->{option_results}->{timeout} = $self->{timeout};
$self->{option_results}->{proxyurl} = $self->{proxyurl};
$self->{option_results}->{ssl_opt} = $self->{ssl_opt};
$self->{option_results}->{warning_status} = '';
$self->{option_results}->{critical_status} = '';
$self->{option_results}->{unknown_status} = '';
}
sub settings {
my ($self, %options) = @_;
$self->build_options_for_httplib();
$self->{http}->add_header(key => 'Accept', value => 'application/json');
$self->{http}->add_header(key => 'Content-Type', value => 'application/x-www-form-urlencoded');
if (defined($self->{access_token})) {
$self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{access_token});
}
$self->{http}->set_options(%{$self->{option_results}});
}
sub get_access_token {
my ($self, %options) = @_;
my $has_cache_file = $options{statefile}->read(statefile => 'office365_graphapi_' . md5_hex($self->{tenant}) . '_' . md5_hex($self->{client_id}));
my $expires_on = $options{statefile}->get(name => 'expires_on');
my $access_token = $options{statefile}->get(name => 'access_token');
if ($has_cache_file == 0 || !defined($access_token) || (($expires_on - time()) < 10)) {
my $uri = URI::Encode->new({encode_reserved => 1});
my $encoded_graph_endpoint = $uri->encode($self->{graph_endpoint} . '/.default');
my $post_data = 'grant_type=client_credentials' .
'&client_id=' . $self->{client_id} .
'&client_secret=' . $self->{client_secret} .
'&scope=' . $encoded_graph_endpoint;
$self->settings();
my $content = $self->{http}->request(method => 'POST', query_form_post => $post_data,
full_url => $self->{login_endpoint} . '/' . $self->{tenant} . '/oauth2/v2.0/token',
hostname => '');
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($content);
};
if ($@) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot decode json response");
$self->{output}->option_exit();
}
if (defined($decoded->{error})) {
$self->{output}->output_add(long_msg => "Error message : " . $decoded->{error_description}, debug => 1);
$self->{output}->add_option_msg(short_msg => "Login endpoint API return error code '" . $decoded->{error} . "' (add --debug option for detailed message)");
$self->{output}->option_exit();
}
$access_token = $decoded->{access_token};
my $datas = { last_timestamp => time(), access_token => $decoded->{access_token}, expires_on => time() + $decoded->{expires_in} };
$options{statefile}->write(data => $datas);
}
return $access_token;
}
sub request_api_json {
my ($self, %options) = @_;
if (!defined($self->{access_token})) {
$self->{access_token} = $self->get_access_token(statefile => $self->{cache});
}
$self->settings();
my $content = $self->{http}->request(%options);
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($content);
};
if ($@) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
if (defined($decoded->{error})) {
$self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}->{message}, debug => 1);
$self->{output}->add_option_msg(short_msg => "Graph endpoint API return error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)");
$self->{output}->option_exit();
}
return $decoded;
}
sub request_api_csv {
my ($self, %options) = @_;
if (!defined($self->{access_token})) {
$self->{access_token} = $self->get_access_token(statefile => $self->{cache});
}
$self->settings();
my $content = $self->{http}->request(%options);
my $response = $self->{http}->get_response();
if ($response->code() != 200) {
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($content);
};
if ($@) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
if (defined($decoded->{error})) {
$self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}->{message}, debug => 1);
$self->{output}->add_option_msg(short_msg => "Graph endpoint API return error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)");
$self->{output}->option_exit();
}
}
my $decoded;
eval {
$decoded = decode('UTF-8', $content);
};
if ($@) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot decode response: $@");
$self->{output}->option_exit();
}
$decoded =~ s/^\x{feff}//;
my @rows;
eval {
open my $fh, '<', \$decoded;
my $csv = Text::CSV->new({ binary => 1 });
$csv->column_names($csv->getline($fh));
while (my $row = $csv->getline_hr($fh)) {
push @rows, $row;
}
};
if ($@) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot parse csv response: $@");
$self->{output}->option_exit();
}
return \@rows;
}
sub office_get_sharepoint_site_usage_set_url {
my ($self, %options) = @_;
my $url = $self->{graph_endpoint} . "/v1.0/reports/getSharePointSiteUsageDetail(period='D7')";
return $url;
}
sub office_get_sharepoint_site_usage {
my ($self, %options) = @_;
my $full_url = $self->office_get_sharepoint_site_usage_set_url(%options);
my $response = $self->request_api_csv(method => 'GET', full_url => $full_url, hostname => '');
return $response;
}
sub office_get_sharepoint_activity_set_url {
my ($self, %options) = @_;
my $url = $self->{graph_endpoint} . "/v1.0/reports/getSharePointActivityUserDetail(period='D7')";
return $url;
}
sub office_get_sharepoint_activity {
my ($self, %options) = @_;
my $full_url = $self->office_get_sharepoint_activity_set_url(%options);
my $response = $self->request_api_csv(method => 'GET', full_url => $full_url, hostname => '');
return $response;
}
sub office_get_onedrive_usage_set_url {
my ($self, %options) = @_;
my $url = $self->{graph_endpoint} . "/v1.0/reports/getOneDriveUsageAccountDetail(period='D7')";
return $url;
}
sub office_get_onedrive_usage {
my ($self, %options) = @_;
my $full_url = $self->office_get_onedrive_usage_set_url(%options);
my $response = $self->request_api_csv(method => 'GET', full_url => $full_url, hostname => '');
return $response;
}
sub office_get_exchange_activity_set_url {
my ($self, %options) = @_;
my $url = $self->{graph_endpoint} . "/v1.0/reports/getEmailActivityUserDetail(period='D7')";
return $url;
}
sub office_get_exchange_activity {
my ($self, %options) = @_;
my $full_url = $self->office_get_exchange_activity_set_url(%options);
my $response = $self->request_api_csv(method => 'GET', full_url => $full_url, hostname => '');
return $response;
}
sub office_get_exchange_mailbox_usage_set_url {
my ($self, %options) = @_;
my $url = $self->{graph_endpoint} . "/v1.0/reports/getMailboxUsageDetail(period='D7')";
return $url;
}
sub office_get_exchange_mailbox_usage {
my ($self, %options) = @_;
my $full_url = $self->office_get_exchange_mailbox_usage_set_url(%options);
my $response = $self->request_api_csv(method => 'GET', full_url => $full_url, hostname => '');
return $response;
}
1;
__END__
=head1 NAME
Microsoft Office 365 Graph API
=head1 REST API OPTIONS
Microsoft Office 365 Graph API
To connect to the Office 365 Graph API, you must register an application.
# Follow the 'How-to guide' in https://docs.microsoft.com/en-us/graph/auth-register-app-v2?view=graph-rest-1.0
This custom mode is using the 'OAuth 2.0 Client Credentials Grant Flow'.
=over 8
=item B<--tenant>
Set Office 365 tenant ID.
=item B<--client-id>
Set Office 365 client ID.
=item B<--client-secret>
Set Office 365 client secret.
=item B<--login-endpoint>
Set Office 365 login endpoint URL (Default: 'https://login.microsoftonline.com')
=item B<--graph-endpoint>
Set Office 365 graph endpoint URL (Default: 'https://graph.microsoft.com')
=item B<--timeout>
Set timeout in seconds (Default: 10).
=item B<--proxyurl>
Proxy URL if any
=back
=head1 DESCRIPTION
B<custom>.
=cut

View File

@ -0,0 +1,304 @@
#
# 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 cloud::microsoft::office365::custom::managementapi;
use strict;
use warnings;
use DateTime;
use centreon::plugins::http;
use centreon::plugins::statefile;
use JSON::XS;
use URI::Encode;
use Digest::MD5 qw(md5_hex);
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
if (!defined($options{output})) {
print "Class Custom: Need to specify 'output' argument.\n";
exit 3;
}
if (!defined($options{options})) {
$options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument.");
$options{output}->option_exit();
}
if (!defined($options{noptions})) {
$options{options}->add_options(arguments =>
{
"tenant:s" => { name => 'tenant' },
"client-id:s" => { name => 'client_id' },
"client-secret:s" => { name => 'client_secret' },
"login-endpoint:s" => { name => 'login_endpoint' },
"management-endpoint:s" => { name => 'management_endpoint' },
"timeout:s" => { name => 'timeout' },
"proxyurl:s" => { name => 'proxyurl' },
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{mode} = $options{mode};
$self->{http} = centreon::plugins::http->new(output => $self->{output});
$self->{cache} = centreon::plugins::statefile->new(%options);
return $self;
}
sub set_options {
my ($self, %options) = @_;
$self->{option_results} = $options{option_results};
}
sub set_defaults {
my ($self, %options) = @_;
foreach (keys %{$options{default}}) {
if ($_ eq $self->{mode}) {
for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) {
foreach my $opt (keys %{$options{default}->{$_}[$i]}) {
if (!defined($self->{option_results}->{$opt}[$i])) {
$self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt};
}
}
}
}
}
}
sub check_options {
my ($self, %options) = @_;
$self->{tenant} = (defined($self->{option_results}->{tenant})) ? $self->{option_results}->{tenant} : undef;
$self->{client_id} = (defined($self->{option_results}->{client_id})) ? $self->{option_results}->{client_id} : undef;
$self->{client_secret} = (defined($self->{option_results}->{client_secret})) ? $self->{option_results}->{client_secret} : undef;
$self->{login_endpoint} = (defined($self->{option_results}->{login_endpoint})) ? $self->{option_results}->{login_endpoint} : 'https://login.windows.net';
$self->{management_endpoint} = (defined($self->{option_results}->{management_endpoint})) ? $self->{option_results}->{management_endpoint} : 'https://manage.office.com';
$self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10;
$self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef;
$self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef;
if (!defined($self->{tenant}) || $self->{tenant} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --tenant option.");
$self->{output}->option_exit();
}
if (!defined($self->{client_id}) || $self->{client_id} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --client-id option.");
$self->{output}->option_exit();
}
if (!defined($self->{client_secret}) || $self->{client_secret} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify --client-secret option.");
$self->{output}->option_exit();
}
$self->{cache}->check_options(option_results => $self->{option_results});
return 0;
}
sub build_options_for_httplib {
my ($self, %options) = @_;
$self->{option_results}->{timeout} = $self->{timeout};
$self->{option_results}->{proxyurl} = $self->{proxyurl};
$self->{option_results}->{ssl_opt} = $self->{ssl_opt};
$self->{option_results}->{warning_status} = '';
$self->{option_results}->{critical_status} = '';
$self->{option_results}->{unknown_status} = '';
}
sub settings {
my ($self, %options) = @_;
$self->build_options_for_httplib();
$self->{http}->add_header(key => 'Accept', value => 'application/json');
$self->{http}->add_header(key => 'Content-Type', value => 'application/x-www-form-urlencoded');
if (defined($self->{access_token})) {
$self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{access_token});
}
$self->{http}->set_options(%{$self->{option_results}});
}
sub get_access_token {
my ($self, %options) = @_;
my $has_cache_file = $options{statefile}->read(statefile => 'office365_managementapi_' . md5_hex($self->{tenant}) . '_' . md5_hex($self->{client_id}));
my $expires_on = $options{statefile}->get(name => 'expires_on');
my $access_token = $options{statefile}->get(name => 'access_token');
if ($has_cache_file == 0 || !defined($access_token) || (($expires_on - time()) < 10)) {
my $uri = URI::Encode->new({encode_reserved => 1});
my $encoded_management_endpoint = $uri->encode($self->{management_endpoint});
my $post_data = 'grant_type=client_credentials' .
'&client_id=' . $self->{client_id} .
'&client_secret=' . $self->{client_secret} .
'&resource=' . $encoded_management_endpoint;
$self->settings();
my $content = $self->{http}->request(method => 'POST', query_form_post => $post_data,
full_url => $self->{login_endpoint} . '/' . $self->{tenant} . '/oauth2/token?api-version=1.0',
hostname => '');
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($content);
};
if ($@) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot decode json response");
$self->{output}->option_exit();
}
if (defined($decoded->{error})) {
$self->{output}->output_add(long_msg => "Error message : " . $decoded->{error_description}, debug => 1);
$self->{output}->add_option_msg(short_msg => "Login endpoint API return error code '" . $decoded->{error} . "' (add --debug option for detailed message)");
$self->{output}->option_exit();
}
$access_token = $decoded->{access_token};
my $datas = { last_timestamp => time(), access_token => $decoded->{access_token}, expires_on => $decoded->{expires_on} };
$options{statefile}->write(data => $datas);
}
return $access_token;
}
sub request_api {
my ($self, %options) = @_;
if (!defined($self->{access_token})) {
$self->{access_token} = $self->get_access_token(statefile => $self->{cache});
}
$self->settings();
my $content = $self->{http}->request(%options);
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($content);
};
if ($@) {
$self->{output}->output_add(long_msg => $content, debug => 1);
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
if (defined($decoded->{error})) {
$self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}->{message}, debug => 1);
$self->{output}->add_option_msg(short_msg => "Management endpoint API return error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)");
$self->{output}->option_exit();
}
return $decoded;
}
sub office_get_services_status_set_url {
my ($self, %options) = @_;
my $url = $self->{management_endpoint} . "/api/v1.0/" . $self->{tenant} . "/ServiceComms/CurrentStatus";
return $url;
}
sub office_get_services_status {
my ($self, %options) = @_;
my $full_url = $self->office_get_services_status_set_url(%options);
my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => '');
return $response;
}
sub office_list_services_set_url {
my ($self, %options) = @_;
my $url = $self->{management_endpoint} . "/api/v1.0/" . $self->{tenant} . "/ServiceComms/Services";
return $url;
}
sub office_list_services {
my ($self, %options) = @_;
my $full_url = $self->office_list_services_set_url(%options);
my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => '');
return $response;
}
1;
__END__
=head1 NAME
Microsoft Office 365 Management API
=head1 REST API OPTIONS
Microsoft Office 365 Management API
To connect to the Office 365 Management API, you must register an application.
Follow the 'How-to guide' in https://docs.microsoft.com/en-us/office/office-365-management-api/get-started-with-office-365-management-apis#register-your-application-in-azure-ad
This custom mode is using the 'OAuth 2.0 Client Credentials Grant Flow'.
=over 8
=item B<--tenant>
Set Office 365 tenant ID.
=item B<--client-id>
Set Office 365 client ID.
=item B<--client-secret>
Set Office 365 client secret.
=item B<--login-endpoint>
Set Office 365 login endpoint URL (Default: 'https://login.windows.net')
=item B<--management-endpoint>
Set Office 365 management endpoint URL (Default: 'https://manage.office.com')
=item B<--timeout>
Set timeout in seconds (Default: 10).
=item B<--proxyurl>
Proxy URL if any
=back
=head1 DESCRIPTION
B<custom>.
=cut

View File

@ -0,0 +1,161 @@
#
# 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 cloud::microsoft::office365::exchange::mode::emailactivity;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub prefix_mailbox_output {
my ($self, %options) = @_;
return "User '" . $options{instance_value}->{name} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'mailboxes', type => 1, cb_prefix_output => 'prefix_mailbox_output', message_multiple => 'All email activity are ok' },
];
$self->{maps_counters}->{mailboxes} = [
{ label => 'send-count', set => {
key_values => [ { name => 'send_count' }, { name => 'name' } ],
output_template => 'Send Count: %d',
perfdatas => [
{ label => 'send_count', value => 'send_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'name_absolute' },
],
}
},
{ label => 'receive-count', set => {
key_values => [ { name => 'receive_count' }, { name => 'name' } ],
output_template => 'Receive Count: %d',
perfdatas => [
{ label => 'receive_count', value => 'receive_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'name_absolute' },
],
}
},
{ label => 'read-count', set => {
key_values => [ { name => 'read_count' }, { name => 'name' } ],
output_template => 'Read Count: %d',
perfdatas => [
{ label => 'read_count', value => 'read_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'name_absolute' },
],
}
},
{ label => 'last-activity', threshold => 0, set => {
key_values => [ { name => 'last_activity_date' }, { name => 'name' } ],
output_template => 'Last Activity: %s',
}
},
];
}
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-mailbox:s" => { name => 'filter_mailbox' },
"active-only" => { name => 'active_only' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
$self->{mailboxes} = {};
my $results = $options{custom}->office_get_exchange_activity();
foreach my $mailbox (@{$results}) {
if (defined($self->{option_results}->{filter_mailbox}) && $self->{option_results}->{filter_mailbox} ne '' &&
$mailbox->{'User Principal Name'} !~ /$self->{option_results}->{filter_mailbox}/) {
$self->{output}->output_add(long_msg => "skipping '" . $mailbox->{'User Principal Name'} . "': no matching filter name.", debug => 1);
next;
}
if ($self->{option_results}->{active_only} && defined($mailbox->{'Last Activity Date'}) && $mailbox->{'Last Activity Date'} eq '') {
$self->{output}->output_add(long_msg => "skipping '" . $mailbox->{'User Principal Name'} . "': no activity.", debug => 1);
next;
}
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{name} = $mailbox->{'User Principal Name'};
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{send_count} = $mailbox->{'Send Count'};
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{receive_count} = $mailbox->{'Receive Count'};
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{read_count} = $mailbox->{'Read Count'};
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{last_activity_date} = $mailbox->{'Last Activity Date'};
}
if (scalar(keys %{$self->{mailboxes}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check email activity (reporting period over the last 7 days).
(See link for details about metrics :
https://docs.microsoft.com/en-us/office365/admin/activity-reports/email-activity?view=o365-worldwide)
=over 8
=item B<--filter-mailbox>
Filter mailboxes.
=item B<--warning-*>
Threshold warning.
Can be: 'send-count', 'receive-count', 'read-count'.
=item B<--critical-*>
Threshold critical.
Can be: 'send-count', 'receive-count', 'read-count'.
=item B<--active-only>
Filter only active entries ('Last Activity' set).
=back
=cut

View File

@ -0,0 +1,224 @@
#
# 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 cloud::microsoft::office365::exchange::mode::mailboxusage;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
my $instance_mode;
sub custom_usage_perfdata {
my ($self, %options) = @_;
my $extra_label = '';
$extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0);
$self->{output}->perfdata_add(label => 'used' . $extra_label,
unit => 'B',
value => $self->{result_values}->{used},
min => 0);
}
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 ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($issue_warning_quota_value, $issue_warning_quota_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{issue_warning_quota});
my ($prohibit_send_quota_value, $prohibit_send_quota_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{prohibit_send_quota});
my ($prohibit_send_receive_quota_value, $prohibit_send_receive_quota_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{prohibit_send_receive_quota});
my $msg = sprintf("Used: %s Issue Warning Quota: %s Prohibit Send Quota: %s Prohibit Send/Receive Quota: %s",
$used_value . " " . $used_unit,
$issue_warning_quota_value . " " . $issue_warning_quota_unit,
$prohibit_send_quota_value . " " . $prohibit_send_quota_unit,
$prohibit_send_receive_quota_value . " " . $prohibit_send_receive_quota_unit);
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_name'};
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_storage_used'};
$self->{result_values}->{issue_warning_quota} = $options{new_datas}->{$self->{instance} . '_issue_warning_quota'};
$self->{result_values}->{prohibit_send_quota} = $options{new_datas}->{$self->{instance} . '_prohibit_send_quota'};
$self->{result_values}->{prohibit_send_receive_quota} = $options{new_datas}->{$self->{instance} . '_prohibit_send_receive_quota'};
return 0;
}
sub prefix_mailbox_output {
my ($self, %options) = @_;
return "Mailbox '" . $options{instance_value}->{name} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'mailboxes', type => 1, cb_prefix_output => 'prefix_mailbox_output', message_multiple => 'All mailboxes usage are ok' },
];
$self->{maps_counters}->{mailboxes} = [
{ label => 'usage', set => {
key_values => [ { name => 'storage_used' }, { name => 'issue_warning_quota' },
{ name => 'prohibit_send_quota' }, { name => 'prohibit_send_receive_quota' }, { name => 'name' } ],
closure_custom_calc => $self->can('custom_status_calc'),
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
closure_custom_threshold_check => $self->can('custom_status_threshold'),
}
},
{ label => 'last-activity', threshold => 0, set => {
key_values => [ { name => 'last_activity_date' }, { name => 'name' } ],
output_template => 'Last Activity: %s',
}
},
];
}
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-mailbox:s" => { name => 'filter_mailbox' },
"warning-status:s" => { name => 'warning_status', default => '%{used} > %{issue_warning_quota}' },
"critical-status:s" => { name => 'critical_status', default => '%{used} > %{prohibit_send_quota}' },
"active-only" => { name => 'active_only' },
});
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->{mailboxes} = {};
my $results = $options{custom}->office_get_exchange_mailbox_usage();
foreach my $mailbox (@{$results}) {
if (defined($self->{option_results}->{filter_mailbox}) && $self->{option_results}->{filter_mailbox} ne '' &&
$mailbox->{'User Principal Name'} !~ /$self->{option_results}->{filter_mailbox}/) {
$self->{output}->output_add(long_msg => "skipping '" . $mailbox->{'User Principal Name'} . "': no matching filter name.", debug => 1);
next;
}
if ($self->{option_results}->{active_only} && defined($mailbox->{'Last Activity Date'}) && $mailbox->{'Last Activity Date'} eq '') {
$self->{output}->output_add(long_msg => "skipping '" . $mailbox->{'User Principal Name'} . "': no activity.", debug => 1);
next;
}
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{name} = $mailbox->{'User Principal Name'};
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{storage_used} = ($mailbox->{'Storage Used (Byte)'} ne '') ? $mailbox->{'Storage Used (Byte)'} : 0;
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{issue_warning_quota} = $mailbox->{'Issue Warning Quota (Byte)'};
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{prohibit_send_quota} = $mailbox->{'Prohibit Send Quota (Byte)'};
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{prohibit_send_receive_quota} = $mailbox->{'Prohibit Send/Receive Quota (Byte)'};
$self->{mailboxes}->{$mailbox->{'User Principal Name'}}->{last_activity_date} = $mailbox->{'Last Activity Date'};
}
if (scalar(keys %{$self->{mailboxes}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check mailbox usage (reporting period over the last 7 days).
(See link for details about metrics :
https://docs.microsoft.com/en-us/office365/admin/activity-reports/mailbox-usage?view=o365-worldwide)
=over 8
=item B<--filter-mailbox>
Filter mailboxes.
=item B<--warning-status>
Set warning threshold for status (Default: '%{used} > %{issue_warning_quota}').
Can used special variables like: %{used}, %{issue_warning_quota}, %{prohibit_send_quota}, %{prohibit_send_receive_quota}
=item B<--critical-status>
Set critical threshold for status (Default: '%{used} > %{prohibit_send_quota}').
Can used special variables like: %{used}, %{issue_warning_quota}, %{prohibit_send_quota}, %{prohibit_send_receive_quota}
=item B<--active-only>
Filter only active entries ('Last Activity' set).
=back
=cut

View File

@ -0,0 +1,50 @@
#
# 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 cloud::microsoft::office365::exchange::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ( $class, %options ) = @_;
my $self = $class->SUPER::new( package => __PACKAGE__, %options );
bless $self, $class;
$self->{version} = '0.1';
%{ $self->{modes} } = (
'email-activity' => 'cloud::microsoft::office365::exchange::mode::emailactivity',
'mailbox-usage' => 'cloud::microsoft::office365::exchange::mode::mailboxusage',
);
$self->{custom_modes}{graphapi} = 'cloud::microsoft::office365::custom::graphapi';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Microsoft Office 365 Exchange.
=cut

View File

@ -0,0 +1,116 @@
#
# 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 cloud::microsoft::office365::management::mode::listservices;
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;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"filter-name:s" => { name => 'filter_name' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->office_list_services();
foreach my $service (@{$results->{value}}) {
if (defined($self->{option_results}->{filter_service_name}) && $self->{option_results}->{filter_service_name} ne '' &&
$service->{WorkloadDisplayName} !~ /$self->{option_results}->{filter_service_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $service->{WorkloadDisplayName} . "': no matching filter name.", debug => 1);
next;
}
$self->{services}->{$service->{Id}} = {
service_id => $service->{Id},
service_name => $service->{DisplayName},
}
}
}
sub run {
my ($self, %options) = @_;
$self->manage_selection(%options);
foreach my $service (sort keys %{$self->{services}}) {
$self->{output}->output_add(long_msg => sprintf("[service_id = %s] [service_name = %s]",
$self->{services}->{$service}->{service_id},
$self->{services}->{$service}->{service_name}));
}
$self->{output}->output_add(severity => 'OK',
short_msg => 'List services:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['service_id', 'service_name']);
}
sub disco_show {
my ($self, %options) = @_;
$self->manage_selection(%options);
foreach my $service (sort keys %{$self->{services}}) {
$self->{output}->add_disco_entry(
service_id => $self->{services}->{$service}->{service_id},
service_name => $self->{services}->{$service}->{service_name},
);
}
}
1;
__END__
=head1 MODE
List services.
=over 8
=item B<--filter-name>
Filter service name (can be a regexp).
=back
=cut

View File

@ -0,0 +1,205 @@
#
# 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 cloud::microsoft::office365::management::mode::servicestatus;
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 = "status is '" . $self->{result_values}->{status} . "'";
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'};
return 0;
}
sub prefix_service_output {
my ($self, %options) = @_;
return "Service '" . $options{instance_value}->{service_name} . "' ";
}
sub prefix_feature_output {
my ($self, %options) = @_;
return "Service '" . $options{instance_value}->{service_name} . "' Feature '" . $options{instance_value}->{feature_name} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'services', type => 3, cb_prefix_output => 'prefix_service_output', message_multiple => 'All services status are ok',
counters => [ { name => 'features', type => 1, cb_prefix_output => 'prefix_feature_output', message_multiple => 'All features status are ok' } ] },
];
$self->{maps_counters}->{services} = [
{ label => 'status', set => {
key_values => [ { name => 'status' }, { name => 'service_name' } ],
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'),
}
},
];
$self->{maps_counters}->{features} = [
{ label => 'status', set => {
key_values => [ { name => 'status' }, { name => 'service_name' }, { name => 'feature_name' } ],
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-service-name:s" => { name => 'filter_service_name' },
"filter-feature-name:s" => { name => 'filter_feature_name' },
"warning-status:s" => { name => 'warning_status' },
"critical-status:s" => { name => 'critical_status', default => '%{status} !~ /Normal/i' },
});
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->{services} = {};
my $results = $options{custom}->office_get_services_status();
foreach my $service (@{$results->{value}}) {
if (defined($self->{option_results}->{filter_service_name}) && $self->{option_results}->{filter_service_name} ne '' &&
$service->{WorkloadDisplayName} !~ /$self->{option_results}->{filter_service_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $service->{WorkloadDisplayName} . "': no matching filter name.", debug => 1);
next;
}
$self->{services}->{$service->{Id}}->{service_name} = $service->{WorkloadDisplayName};
$self->{services}->{$service->{Id}}->{status} = $service->{StatusDisplayName};
foreach my $feature (@{$service->{FeatureStatus}}) {
if (defined($self->{option_results}->{filter_feature_name}) && $self->{option_results}->{filter_feature_name} ne '' &&
$feature->{FeatureDisplayName} !~ /$self->{option_results}->{filter_feature_name}/) {
$self->{output}->output_add(long_msg => "skipping '" . $feature->{FeatureDisplayName} . "': no matching filter name.", debug => 1);
next;
}
$self->{services}->{$service->{Id}}->{features}->{$feature->{FeatureName}}->{service_name} = $service->{WorkloadDisplayName};
$self->{services}->{$service->{Id}}->{features}->{$feature->{FeatureName}}->{feature_name} = $feature->{FeatureDisplayName};
$self->{services}->{$service->{Id}}->{features}->{$feature->{FeatureName}}->{status} = $feature->{FeatureServiceStatusDisplayName};
}
}
if (scalar(keys %{$self->{services}}) <= 0) {
$self->{output}->add_option_msg(short_msg => 'No services found.');
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check services and features status.
=over 8
=item B<--filter-*>
Filter services and/or features.
Can be: 'service-name', 'feature-name' (can be a regexp).
=item B<--warning-status>
Set warning threshold for status (Default: '').
Can used special variables like: %{service_name}, %{feature_name}, %{status}
=item B<--critical-status>
Set critical threshold for status (Default: '%{status} !~ /Normal/i').
Can used special variables like: %{service_name}, %{feature_name}, %{status}
=back
=cut

View File

@ -0,0 +1,50 @@
#
# 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 cloud::microsoft::office365::management::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ( $class, %options ) = @_;
my $self = $class->SUPER::new( package => __PACKAGE__, %options );
bless $self, $class;
$self->{version} = '0.1';
%{ $self->{modes} } = (
'list-services' => 'cloud::microsoft::office365::management::mode::listservices',
'service-status' => 'cloud::microsoft::office365::management::mode::servicestatus',
);
$self->{custom_modes}{managementapi} = 'cloud::microsoft::office365::custom::managementapi';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Microsoft Office 365.
=cut

View File

@ -0,0 +1,123 @@
#
# 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 cloud::microsoft::office365::onedrive::mode::listsites;
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;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"filter-url:s" => { name => 'filter_url' },
"filter-owner:s" => { name => 'filter_owner' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->office_get_onedrive_usage();
foreach my $site (@{$results}) {
if (defined($self->{option_results}->{filter_url}) && $self->{option_results}->{filter_url} ne '' &&
$site->{'Site URL'} !~ /$self->{option_results}->{filter_url}/) {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Site URL'} . "': no matching filter name.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_owner}) && $self->{option_results}->{filter_owner} ne '' &&
$site->{'Owner Display Name'} !~ /$self->{option_results}->{filter_owner}/) {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Owner Display Name'} . "': no matching filter name.", debug => 1);
next;
}
$self->{sites}->{$site->{'Site URL'}} = {
owner => $site->{'Owner Display Name'},
url => $site->{'Site URL'},
}
}
}
sub run {
my ($self, %options) = @_;
$self->manage_selection(%options);
foreach my $site (sort keys %{$self->{sites}}) {
$self->{output}->output_add(long_msg => sprintf("[owner = %s] [url = %s]",
$self->{sites}->{$site}->{owner},
$self->{sites}->{$site}->{url}));
}
$self->{output}->output_add(severity => 'OK',
short_msg => 'List sites:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['owner', 'url']);
}
sub disco_show {
my ($self, %options) = @_;
$self->manage_selection(%options);
foreach my $site (sort keys %{$self->{sites}}) {
$self->{output}->add_disco_entry(
owner => $self->{sites}->{$site}->{owner},
url => $self->{sites}->{$site}->{url},
);
}
}
1;
__END__
=head1 MODE
List sites.
=over 8
=item B<--filter-*>
Filter sites.
Can be: 'url', 'id' (can be a regexp).
=back
=cut

View File

@ -0,0 +1,239 @@
#
# 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 cloud::microsoft::office365::onedrive::mode::usage;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
my $instance_mode;
sub custom_usage_perfdata {
my ($self, %options) = @_;
my $extra_label = '';
$extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0);
$self->{output}->perfdata_add(label => 'used' . $extra_label,
unit => 'B',
value => $self->{result_values}->{used},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1),
min => 0, max => $self->{result_values}->{total});
}
sub custom_usage_threshold {
my ($self, %options) = @_;
my ($exit, $threshold_value);
$threshold_value = $self->{result_values}->{used};
$threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free}));
if ($instance_mode->{option_results}->{units} eq '%') {
$threshold_value = $self->{result_values}->{prct_used};
$threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free}));
}
$exit = $self->{perfdata}->threshold_check(value => $threshold_value,
threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' },
{ label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]);
return $exit;
}
sub custom_usage_output {
my ($self, %options) = @_;
my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
$total_value . " " . $total_unit,
$used_value . " " . $used_unit, $self->{result_values}->{prct_used},
$free_value . " " . $free_unit, $self->{result_values}->{prct_free});
return $msg;
}
sub custom_usage_calc {
my ($self, %options) = @_;
$self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_url'};
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_storage_allocated'};
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_storage_used'};
if ($self->{result_values}->{total} != 0) {
$self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used};
$self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total};
$self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used};
} else {
$self->{result_values}->{free} = '0';
$self->{result_values}->{prct_used} = '0';
$self->{result_values}->{prct_free} = '0';
}
return 0;
}
sub prefix_site_output {
my ($self, %options) = @_;
return "Site '" . $options{instance_value}->{url} . "' [Owner: " . $options{instance_value}->{owner} . "] ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'sites', type => 1, cb_prefix_output => 'prefix_site_output', message_multiple => 'All sites usage are ok' },
];
$self->{maps_counters}->{sites} = [
{ label => 'usage', set => {
key_values => [ { name => 'storage_used' }, { name => 'storage_allocated' }, { name => 'url' }, { name => 'owner' } ],
closure_custom_calc => $self->can('custom_usage_calc'),
closure_custom_output => $self->can('custom_usage_output'),
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
closure_custom_threshold_check => $self->can('custom_usage_threshold'),
}
},
{ label => 'file-count', set => {
key_values => [ { name => 'file_count' }, { name => 'url' }, { name => 'owner' } ],
output_template => 'File Count: %d',
perfdatas => [
{ label => 'file_count', value => 'file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'url_absolute' },
],
}
},
{ label => 'active-file-count', set => {
key_values => [ { name => 'active_file_count' }, { name => 'url' }, { name => 'owner' } ],
output_template => 'Active File Count: %d',
perfdatas => [
{ label => 'active_file_count', value => 'active_file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'url_absolute' },
],
}
},
{ label => 'last-activity', threshold => 0, set => {
key_values => [ { name => 'last_activity_date' }, { name => 'url' }, { name => 'owner' } ],
output_template => 'Last Activity: %s',
}
},
];
}
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-url:s" => { name => 'filter_url' },
"filter-owner:s" => { name => 'filter_owner' },
"units:s" => { name => 'units', default => '%' },
"free" => { name => 'free' },
"active-only" => { name => 'active_only' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$instance_mode = $self;
}
sub manage_selection {
my ($self, %options) = @_;
$self->{sites} = {};
my $results = $options{custom}->office_get_onedrive_usage();
foreach my $site (@{$results}) {
if (defined($self->{option_results}->{filter_url}) && $self->{option_results}->{filter_url} ne '' &&
$site->{'Site URL'} !~ /$self->{option_results}->{filter_url}/) {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Site URL'} . "': no matching filter name.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_owner}) && $self->{option_results}->{filter_owner} ne '' &&
$site->{'Owner Display Name'} !~ /$self->{option_results}->{filter_owner}/) {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Owner Display Name'} . "': no matching filter name.", debug => 1);
next;
}
if ($self->{option_results}->{active_only} && defined($site->{'Last Activity Date'}) && $site->{'Last Activity Date'} eq '') {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Site URL'} . "': no activity.", debug => 1);
next;
}
$self->{sites}->{$site->{'Site URL'}}->{url} = $site->{'Site URL'};
$self->{sites}->{$site->{'Site URL'}}->{owner} = $site->{'Owner Display Name'};
$self->{sites}->{$site->{'Site URL'}}->{file_count} = $site->{'File Count'};
$self->{sites}->{$site->{'Site URL'}}->{active_file_count} = $site->{'Active File Count'};
$self->{sites}->{$site->{'Site URL'}}->{storage_used} = $site->{'Storage Used (Byte)'};
$self->{sites}->{$site->{'Site URL'}}->{storage_allocated} = $site->{'Storage Allocated (Byte)'};
$self->{sites}->{$site->{'Site URL'}}->{last_activity_date} = $site->{'Last Activity Date'};
}
if (scalar(keys %{$self->{sites}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check usage (reporting period over the last 7 days).
(See link for details about metrics :
https://docs.microsoft.com/en-us/office365/admin/activity-reports/onedrive-for-business-usage?view=o365-worldwide)
=over 8
=item B<--filter-*>
Filter sites.
Can be: 'url', 'owner' (can be a regexp).
=item B<--warning-*>
Threshold warning.
Can be: 'usage', 'file-count', 'active-file-count'.
=item B<--critical-*>
Threshold critical.
Can be: 'usage', 'file-count', 'active-file-count'.
=item B<--active-only>
Filter only active entries ('Last Activity' set).
=back
=cut

View File

@ -0,0 +1,50 @@
#
# 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 cloud::microsoft::office365::onedrive::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ( $class, %options ) = @_;
my $self = $class->SUPER::new( package => __PACKAGE__, %options );
bless $self, $class;
$self->{version} = '0.1';
%{ $self->{modes} } = (
'list-sites' => 'cloud::microsoft::office365::onedrive::mode::listsites',
'usage' => 'cloud::microsoft::office365::onedrive::mode::usage',
);
$self->{custom_modes}{graphapi} = 'cloud::microsoft::office365::custom::graphapi';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Microsoft Office 365 OneDrive.
=cut

View File

@ -0,0 +1,123 @@
#
# 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 cloud::microsoft::office365::sharepoint::mode::listsites;
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;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"filter-url:s" => { name => 'filter_url' },
"filter-id:s" => { name => 'filter_id' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->office_get_sharepoint_site_usage();
foreach my $site (@{$results}) {
if (defined($self->{option_results}->{filter_url}) && $self->{option_results}->{filter_url} ne '' &&
$site->{'Site URL'} !~ /$self->{option_results}->{filter_url}/) {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Site URL'} . "': no matching filter name.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' &&
$site->{'Site Id'} !~ /$self->{option_results}->{filter_id}/) {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Site Id'} . "': no matching filter name.", debug => 1);
next;
}
$self->{sites}->{$site->{'Site Id'}} = {
id => $site->{'Site Id'},
url => $site->{'Site URL'},
}
}
}
sub run {
my ($self, %options) = @_;
$self->manage_selection(%options);
foreach my $site (sort keys %{$self->{sites}}) {
$self->{output}->output_add(long_msg => sprintf("[id = %s] [url = %s]",
$self->{sites}->{$site}->{id},
$self->{sites}->{$site}->{url}));
}
$self->{output}->output_add(severity => 'OK',
short_msg => 'List sites:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['id', 'url']);
}
sub disco_show {
my ($self, %options) = @_;
$self->manage_selection(%options);
foreach my $site (sort keys %{$self->{sites}}) {
$self->{output}->add_disco_entry(
id => $self->{sites}->{$site}->{id},
url => $self->{sites}->{$site}->{url},
);
}
}
1;
__END__
=head1 MODE
List sites.
=over 8
=item B<--filter-*>
Filter sites.
Can be: 'url', 'id' (can be a regexp).
=back
=cut

View File

@ -0,0 +1,261 @@
#
# 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 cloud::microsoft::office365::sharepoint::mode::siteusage;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
my $instance_mode;
sub custom_usage_perfdata {
my ($self, %options) = @_;
my $extra_label = '';
$extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0);
$self->{output}->perfdata_add(label => 'used' . $extra_label,
unit => 'B',
value => $self->{result_values}->{used},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1),
min => 0, max => $self->{result_values}->{total});
}
sub custom_usage_threshold {
my ($self, %options) = @_;
my ($exit, $threshold_value);
$threshold_value = $self->{result_values}->{used};
$threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free}));
if ($instance_mode->{option_results}->{units} eq '%') {
$threshold_value = $self->{result_values}->{prct_used};
$threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free}));
}
$exit = $self->{perfdata}->threshold_check(value => $threshold_value,
threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' },
{ label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]);
return $exit;
}
sub custom_usage_output {
my ($self, %options) = @_;
my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
$total_value . " " . $total_unit,
$used_value . " " . $used_unit, $self->{result_values}->{prct_used},
$free_value . " " . $free_unit, $self->{result_values}->{prct_free});
return $msg;
}
sub custom_usage_calc {
my ($self, %options) = @_;
$self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_id'};
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_storage_allocated'};
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_storage_used'};
if ($self->{result_values}->{total} != 0) {
$self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used};
$self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total};
$self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used};
} else {
$self->{result_values}->{free} = '0';
$self->{result_values}->{prct_used} = '0';
$self->{result_values}->{prct_free} = '0';
}
return 0;
}
sub prefix_site_output {
my ($self, %options) = @_;
return "Site '" . $options{instance_value}->{url} . "' [ID: " . $options{instance_value}->{id} . "] ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'sites', type => 1, cb_prefix_output => 'prefix_site_output', message_multiple => 'All sites usage are ok' },
];
$self->{maps_counters}->{sites} = [
{ label => 'usage', set => {
key_values => [ { name => 'storage_used' }, { name => 'storage_allocated' }, { name => 'url' }, { name => 'id' } ],
closure_custom_calc => $self->can('custom_usage_calc'),
closure_custom_output => $self->can('custom_usage_output'),
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
closure_custom_threshold_check => $self->can('custom_usage_threshold'),
}
},
{ label => 'file-count', set => {
key_values => [ { name => 'file_count' }, { name => 'url' }, { name => 'id' } ],
output_template => 'File Count: %d',
perfdatas => [
{ label => 'file_count', value => 'file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'id_absolute' },
],
}
},
{ label => 'active-file-count', set => {
key_values => [ { name => 'active_file_count' }, { name => 'url' }, { name => 'id' } ],
output_template => 'Active File Count: %d',
perfdatas => [
{ label => 'active_file_count', value => 'active_file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'id_absolute' },
],
}
},
{ label => 'visited-file-count', set => {
key_values => [ { name => 'visited_file_count' }, { name => 'url' }, { name => 'id' } ],
output_template => 'Visited File Count: %d',
perfdatas => [
{ label => 'visited_file_count', value => 'visited_file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'id_absolute' },
],
}
},
{ label => 'page-view-count', set => {
key_values => [ { name => 'page_view_count' }, { name => 'url' }, { name => 'id' } ],
output_template => 'Page View Count: %d',
perfdatas => [
{ label => 'page_view_count', value => 'page_view_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'id_absolute' },
],
}
},
{ label => 'last-activity', threshold => 0, set => {
key_values => [ { name => 'last_activity_date' }, { name => 'url' }, { name => 'id' } ],
output_template => 'Last Activity: %s',
}
},
];
}
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-url:s" => { name => 'filter_url' },
"filter-id:s" => { name => 'filter_id' },
"units:s" => { name => 'units', default => '%' },
"free" => { name => 'free' },
"active-only" => { name => 'active_only' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$instance_mode = $self;
}
sub manage_selection {
my ($self, %options) = @_;
$self->{sites} = {};
my $results = $options{custom}->office_get_sharepoint_site_usage();
foreach my $site (@{$results}) {
if (defined($self->{option_results}->{filter_url}) && $self->{option_results}->{filter_url} ne '' &&
$site->{'Site URL'} !~ /$self->{option_results}->{filter_url}/) {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Site URL'} . "': no matching filter name.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' &&
$site->{'Site Id'} !~ /$self->{option_results}->{filter_id}/) {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Site Id'} . "': no matching filter name.", debug => 1);
next;
}
if ($self->{option_results}->{active_only} && defined($site->{'Last Activity Date'}) && $site->{'Last Activity Date'} eq '') {
$self->{output}->output_add(long_msg => "skipping '" . $site->{'Site URL'} . "': no activity.", debug => 1);
next;
}
$self->{sites}->{$site->{'Site Id'}}->{id} = $site->{'Site Id'};
$self->{sites}->{$site->{'Site Id'}}->{url} = $site->{'Site URL'};
$self->{sites}->{$site->{'Site Id'}}->{file_count} = $site->{'File Count'};
$self->{sites}->{$site->{'Site Id'}}->{active_file_count} = $site->{'Active File Count'};
$self->{sites}->{$site->{'Site Id'}}->{visited_file_count} = $site->{'Visited Page Count'};
$self->{sites}->{$site->{'Site Id'}}->{page_view_count} = $site->{'Page View Count'};
$self->{sites}->{$site->{'Site Id'}}->{storage_used} = $site->{'Storage Used (Byte)'};
$self->{sites}->{$site->{'Site Id'}}->{storage_allocated} = $site->{'Storage Allocated (Byte)'};
$self->{sites}->{$site->{'Site Id'}}->{last_activity_date} = $site->{'Last Activity Date'};
}
if (scalar(keys %{$self->{sites}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check sites usage (reporting period over the last 7 days).
(See link for details about metrics :
https://docs.microsoft.com/en-us/office365/admin/activity-reports/sharepoint-site-usage?view=o365-worldwide)
=over 8
=item B<--filter-*>
Filter sites.
Can be: 'url', 'id' (can be a regexp).
=item B<--warning-*>
Threshold warning.
Can be: 'usage', 'file-count', 'active-file-count',
'visited-file-count', 'page-view-count'.
=item B<--critical-*>
Threshold critical.
Can be: 'usage', 'file-count', 'active-file-count',
'visited-file-count', 'page-view-count'.
=item B<--active-only>
Filter only active entries ('Last Activity' set).
=back
=cut

View File

@ -0,0 +1,183 @@
#
# 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 cloud::microsoft::office365::sharepoint::mode::usersactivity;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub prefix_user_output {
my ($self, %options) = @_;
return "User '" . $options{instance_value}->{name} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'users', type => 1, cb_prefix_output => 'prefix_user_output', message_multiple => 'All users activity are ok' },
];
$self->{maps_counters}->{users} = [
{ label => 'viewed-edited-file-count', set => {
key_values => [ { name => 'viewed_edited_file_count' }, { name => 'name' } ],
output_template => 'Viewed or Edited File Count: %d',
perfdatas => [
{ label => 'viewed_edited_file_count', value => 'viewed_edited_file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'name_absolute' },
],
}
},
{ label => 'file-count', set => {
key_values => [ { name => 'file_count' }, { name => 'name' } ],
output_template => 'File Count: %d',
perfdatas => [
{ label => 'file_count', value => 'file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'name_absolute' },
],
}
},
{ label => 'shared-int-file-count', set => {
key_values => [ { name => 'shared_int_file_count' }, { name => 'name' } ],
output_template => 'Shared Internally File Count: %d',
perfdatas => [
{ label => 'shared_int_file_count', value => 'shared_int_file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'name_absolute' },
],
}
},
{ label => 'shared-ext-file-count', set => {
key_values => [ { name => 'shared_ext_file_count' }, { name => 'name' } ],
output_template => 'Shared Externally File Count: %d',
perfdatas => [
{ label => 'shared_ext_file_count', value => 'shared_ext_file_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'name_absolute' },
],
}
},
{ label => 'visited-page-count', set => {
key_values => [ { name => 'visited_page_count' }, { name => 'name' } ],
output_template => 'Visited Page Count: %d',
perfdatas => [
{ label => 'visited_page_count', value => 'visited_page_count_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'name_absolute' },
],
}
},
{ label => 'last-activity', threshold => 0, set => {
key_values => [ { name => 'last_activity_date' }, { name => 'name' } ],
output_template => 'Last Activity: %s',
}
},
];
}
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-user:s" => { name => 'filter_user' },
"active-only" => { name => 'active_only' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
$self->{users} = {};
my $results = $options{custom}->office_get_sharepoint_activity();
foreach my $user (@{$results}) {
if (defined($self->{option_results}->{filter_user}) && $self->{option_results}->{filter_user} ne '' &&
$user->{'User Principal Name'} !~ /$self->{option_results}->{filter_user}/) {
$self->{output}->output_add(long_msg => "skipping '" . $user->{'User Principal Name'} . "': no matching filter name.", debug => 1);
next;
}
if ($self->{option_results}->{active_only} && defined($user->{'Last Activity Date'}) && $user->{'Last Activity Date'} eq '') {
$self->{output}->output_add(long_msg => "skipping '" . $user->{'User Principal Name'} . "': no activity.", debug => 1);
next;
}
$self->{users}->{$user->{'User Principal Name'}}->{name} = $user->{'User Principal Name'};
$self->{users}->{$user->{'User Principal Name'}}->{viewed_edited_file_count} = $user->{'Viewed Or Edited File Count'};
$self->{users}->{$user->{'User Principal Name'}}->{file_count} = $user->{'Synced File Count'};
$self->{users}->{$user->{'User Principal Name'}}->{shared_int_file_count} = $user->{'Shared Internally File Count'};
$self->{users}->{$user->{'User Principal Name'}}->{shared_ext_file_count} = $user->{'Shared Externally File Count'};
$self->{users}->{$user->{'User Principal Name'}}->{visited_page_count} = $user->{'Visited Page Count'};
$self->{users}->{$user->{'User Principal Name'}}->{last_activity_date} = $user->{'Last Activity Date'};
}
if (scalar(keys %{$self->{users}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No entry found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check users activity (reporting period over the last 7 days).
(See link for details about metrics :
https://docs.microsoft.com/en-us/office365/admin/activity-reports/sharepoint-activity?view=o365-worldwide)
=over 8
=item B<--filter-user>
Filter users.
=item B<--warning-*>
Threshold warning.
Can be: 'viewed-edited-file-count', 'file-count', 'shared-int-file-count',
'shared-ext-file-count', 'visited-page-count'.
=item B<--critical-*>
Threshold critical.
Can be: 'viewed-edited-file-count', 'file-count', 'shared-int-file-count',
'shared-ext-file-count', 'visited-page-count'.
=item B<--active-only>
Filter only active entries ('Last Activity' set).
=back
=cut

View File

@ -0,0 +1,51 @@
#
# 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 cloud::microsoft::office365::sharepoint::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ( $class, %options ) = @_;
my $self = $class->SUPER::new( package => __PACKAGE__, %options );
bless $self, $class;
$self->{version} = '0.1';
%{ $self->{modes} } = (
'list-sites' => 'cloud::microsoft::office365::sharepoint::mode::listsites',
'site-usage' => 'cloud::microsoft::office365::sharepoint::mode::siteusage',
'users-activity' => 'cloud::microsoft::office365::sharepoint::mode::usersactivity',
);
$self->{custom_modes}{graphapi} = 'cloud::microsoft::office365::custom::graphapi';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Microsoft Office 365 SharePoint.
=cut

View File

@ -0,0 +1,41 @@
#
# 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 database::mssql::dbi;
use base qw(centreon::plugins::dbi);
use strict;
use warnings;
sub set_version {
my ($self) = @_;
$self->{version} = $self->{instance}->get_info(18); # SQL_DBMS_VER
return if (defined($self->{version}) && $self->{version} ne '');
return if ($self->query(query => q{select SERVERPROPERTY('productversion') as product_version}, continue_error => 1) == 1);
my $row = $self->fetchrow_hashref();
$self->{version} = $row->{product_version};
}
1;
__END__

View File

@ -48,6 +48,7 @@ sub new {
'transactions' => 'database::mssql::mode::transactions',
);
$self->{sql_modes}{dbi} = 'database::mssql::dbi';
return $self;
}

View File

@ -68,8 +68,9 @@ sub check {
$self->{components}->{entity}->{total}++;
$self->{output}->output_add(long_msg => sprintf("entity '%s' status is '%s' [instance = %s]",
$mapping->{$_}->{label}, $result->{$_}, $mapping->{$_}->{label}));
$mapping->{$_}->{label}, defined($result->{$_}) ? $result->{$_} : 'n/a', $mapping->{$_}->{label}));
next if (!defined($result->{$_}));
my $exit = $self->get_severity(section => 'entity', instance => $mapping->{$_}->{label}, value => $result->{$_});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,

View File

@ -42,6 +42,11 @@ sub new {
'memory' => 'centreon::common::fortinet::fortigate::mode::memory',
'sessions' => 'centreon::common::fortinet::fortigate::mode::sessions',
'signatures' => 'centreon::common::fortinet::fortigate::mode::signatures',
'vdom-cpu' => 'centreon::common::fortinet::fortigate::mode::vdomcpu',
'vdom-memory' => 'centreon::common::fortinet::fortigate::mode::vdommemory',
'vdom-session' => 'centreon::common::fortinet::fortigate::mode::vdomsession',
'vdom-state' => 'centreon::common::fortinet::fortigate::mode::vdomstate',
'vdom-usage' => 'centreon::common::fortinet::fortigate::mode::vdomusage',
'virus' => 'centreon::common::fortinet::fortigate::mode::virus',
'vpn' => 'centreon::common::fortinet::fortigate::mode::vpn',
);

View File

@ -65,22 +65,6 @@ my %map_fru_states = (
10 => 'standby',
);
# In MIB 'mib-jnx-chassis'
my $mapping = {
jnxFruName => { oid => '.1.3.6.1.4.1.2636.3.1.15.1.5' },
jnxFruType => { oid => '.1.3.6.1.4.1.2636.3.1.15.1.6', map => \%map_fru_type },
jnxFruState => { oid => '.1.3.6.1.4.1.2636.3.1.15.1.8', map => \%map_fru_states },
jnxFruTemp => { oid => '.1.3.6.1.4.1.2636.3.1.15.1.9' },
jnxFruOfflineReason => { oid => '.1.3.6.1.4.1.2636.3.1.15.1.10', map => \%map_fru_offline },
};
my $oid_jnxFruEntry = '.1.3.6.1.4.1.2636.3.1.15.1';
sub load {
my ($self) = @_;
push @{$self->{request}}, { oid => $oid_jnxFruEntry, start => $mapping->{jnxFruName}->{oid}, end => $mapping->{jnxFruOfflineReason}->{oid} };
}
sub check {
my ($self) = @_;
@ -88,23 +72,31 @@ sub check {
$self->{components}->{fru} = {name => 'frus', total => 0, skip => 0};
return if ($self->check_filter(section => 'fru'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_jnxFruEntry}})) {
next if ($oid !~ /^$mapping->{jnxFruName}->{oid}\.(.*)$/);
my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_jnxFruEntry}, instance => $instance);
my $mapping = {
jnxFruState => { oid => '.1.3.6.1.4.1.2636.3.1.15.1.8', map => \%map_fru_states },
jnxFruTemp => { oid => '.1.3.6.1.4.1.2636.3.1.15.1.9' },
jnxFruOfflineReason => { oid => '.1.3.6.1.4.1.2636.3.1.15.1.10', map => \%map_fru_offline },
};
my $results = $self->{snmp}->get_table(oid => $self->{oids_fru}->{jnxFruEntry}, start => $mapping->{jnxFruState}->{oid}, end => $mapping->{jnxFruOfflineReason}->{oid});
foreach my $instance (sort $self->get_instances(oid_entry => $self->{oids_fru}->{jnxFruEntry}, oid_name => $self->{oids_fru}->{jnxFruName})) {
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
next if ($self->check_filter(section => 'fru', instance => $instance));
next if ($result->{jnxFruState} =~ /empty/i &&
$self->absent_problem(section => 'fru', instance => $instance));
$self->{components}->{fru}->{total}++;
my $name = $self->get_cache(oid_entry => $self->{oids_fru}->{jnxFruEntry}, oid_name => $self->{oids_fru}->{jnxFruName}, instance => $instance);
my $type = $self->get_cache(oid_entry => $self->{oids_fru}->{jnxFruEntry}, oid_name => $self->{oids_fru}->{jnxFruType}, instance => $instance);
$self->{output}->output_add(long_msg => sprintf("Fru '%s' state is %s [instance: %s, type: %s, offline reason: %s]",
$result->{jnxFruName}, $result->{jnxFruState},
$instance, $result->{jnxFruType}, $result->{jnxFruOfflineReason}));
$name, $result->{jnxFruState},
$instance, $map_fru_type{$type}, $result->{jnxFruOfflineReason}));
my $exit = $self->get_severity(section => 'fru', value => $result->{jnxFruState});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Fru '%s' state is %s [offline reason: %s]", $result->{jnxFruName}, $result->{jnxFruState},
short_msg => sprintf("Fru '%s' state is %s [offline reason: %s]", $name, $result->{jnxFruState},
$result->{jnxFruOfflineReason}));
}
@ -112,9 +104,9 @@ sub check {
my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fru-temperature', instance => $instance, value => $result->{jnxFruTemp});
if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit2,
short_msg => sprintf("Fru '%s' temperature is %s degree centigrade", $result->{jnxFruName}, $result->{jnxFruTemp}));
short_msg => sprintf("Fru '%s' temperature is %s degree centigrade", $name, $result->{jnxFruTemp}));
}
$self->{output}->perfdata_add(label => "temp_" . $result->{jnxFruName}, unit => 'C',
$self->{output}->perfdata_add(label => "temp_" . $name, unit => 'C',
value => $result->{jnxFruTemp},
warning => $warn,
critical => $crit);

View File

@ -33,19 +33,6 @@ my %map_operating_states = (
7 => 'standby',
);
# In MIB 'mib-jnx-chassis'
my $mapping = {
jnxOperatingDescr => { oid => '.1.3.6.1.4.1.2636.3.1.13.1.5' },
jnxOperatingState => { oid => '.1.3.6.1.4.1.2636.3.1.13.1.6', map => \%map_operating_states },
};
my $oid_jnxOperatingEntry = '.1.3.6.1.4.1.2636.3.1.13.1';
sub load {
my ($self) = @_;
push @{$self->{request}}, { oid => $oid_jnxOperatingEntry, start => $mapping->{jnxOperatingDescr}->{oid}, end => $mapping->{jnxOperatingState}->{oid} };
}
sub check {
my ($self) = @_;
@ -53,21 +40,26 @@ sub check {
$self->{components}->{operating} = {name => 'operatings', total => 0, skip => 0};
return if ($self->check_filter(section => 'operating'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_jnxOperatingEntry}})) {
next if ($oid !~ /^$mapping->{jnxOperatingDescr}->{oid}\.(.*)$/);
my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_jnxOperatingEntry}, instance => $instance);
my $mapping = {
jnxOperatingState => { oid => '.1.3.6.1.4.1.2636.3.1.13.1.6', map => \%map_operating_states },
};
my $results = $self->{snmp}->get_table(oid => $self->{oids_operating}->{jnxOperatingEntry}, start => $mapping->{jnxOperatingState}->{oid}, end => $mapping->{jnxOperatingState}->{oid});
foreach my $instance (sort $self->get_instances(oid_entry => $self->{oids_operating}->{jnxOperatingEntry}, oid_name => $self->{oids_operating}->{jnxOperatingDescr})) {
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
next if ($self->check_filter(section => 'operating', instance => $instance));
$self->{components}->{operating}->{total}++;
my $desc = $self->get_cache(oid_entry => $self->{oids_operating}->{jnxOperatingEntry}, oid_name => $self->{oids_operating}->{jnxOperatingDescr}, instance => $instance);
$self->{output}->output_add(long_msg => sprintf("Operating '%s' state is %s [instance: %s]",
$result->{jnxOperatingDescr}, $result->{jnxOperatingState}, $instance));
$desc, $result->{jnxOperatingState}, $instance));
my $exit = $self->get_severity(section => 'operating', value => $result->{jnxOperatingState});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Operating '%s' state is %s",
$result->{jnxOperatingDescr}, $result->{jnxOperatingState}));
$desc, $result->{jnxOperatingState}));
}
}
}

View File

@ -24,6 +24,7 @@ use base qw(centreon::plugins::templates::hardware);
use strict;
use warnings;
use centreon::plugins::statefile;
sub set_system {
my ($self, %options) = @_;
@ -31,8 +32,9 @@ sub set_system {
$self->{regexp_threshold_overload_check_section_option} = '^(fru|operating)$';
$self->{regexp_threshold_numeric_check_section_option} = '^(fru-temperature)$';
$self->{cb_hook1} = 'get_type';
$self->{cb_hook1} = 'init_cache';
$self->{cb_hook2} = 'snmp_execute';
$self->{cb_hook3} = 'get_type';
$self->{thresholds} = {
fru => [
@ -67,6 +69,7 @@ sub snmp_execute {
$self->{snmp} = $options{snmp};
$self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request});
$self->write_cache();
}
sub new {
@ -77,11 +80,81 @@ sub new {
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"reload-cache-time:s" => { name => 'reload_cache_time', default => 180 },
});
$self->{statefile_cache} = centreon::plugins::statefile->new(%options);
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$self->{statefile_cache}->check_options(%options);
}
sub init_cache {
my ($self, %options) = @_;
$self->{hostname} = $options{snmp}->get_hostname();
$self->{snmp_port} = $options{snmp}->get_port();
$self->{oids_fru} = {
jnxFruEntry => '.1.3.6.1.4.1.2636.3.1.15.1',
jnxFruName => '.1.3.6.1.4.1.2636.3.1.15.1.5',
jnxFruType => '.1.3.6.1.4.1.2636.3.1.15.1.6',
};
$self->{oids_operating} = {
jnxOperatingEntry => '.1.3.6.1.4.1.2636.3.1.13.1',
jnxOperatingDescr => '.1.3.6.1.4.1.2636.3.1.13.1.5',
};
$self->{write_cache} = 0;
my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_juniper_mseries_' . $self->{hostname} . '_' . $self->{snmp_port});
my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp');
if ($has_cache_file == 0 ||
!defined($timestamp_cache) || ((time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60)) && $self->{option_results}->{reload_cache_time} != '-1') {
push @{$self->{request}}, { oid => $self->{oids_fru}->{jnxFruEntry}, start => $self->{oids_fru}->{jnxFruName}, end => $self->{oids_fru}->{jnxFruType} };
push @{$self->{request}}, { oid => $self->{oids_operating}->{jnxOperatingEntry}, start => $self->{oids_operating}->{jnxOperatingDescr}, end => $self->{oids_operating}->{jnxOperatingDescr} };
$self->{write_cache} = 1;
}
}
sub write_cache {
my ($self, %options) = @_;
if ($self->{write_cache} == 1) {
my $datas = {};
$datas->{last_timestamp} = time();
$datas->{$self->{oids_fru}->{jnxFruEntry}} = $self->{results}->{$self->{oids_fru}->{jnxFruEntry}};
$datas->{$self->{oids_operating}->{jnxOperatingEntry}} = $self->{results}->{$self->{oids_operating}->{jnxOperatingEntry}};
$self->{statefile_cache}->write(data => $datas);
} else {
$self->{results}->{$self->{oids_fru}->{jnxFruEntry}} = $self->{statefile_cache}->get(name => $self->{oids_fru}->{jnxFruEntry});
$self->{results}->{$self->{oids_operating}->{jnxOperatingEntry}} = $self->{statefile_cache}->get(name => $self->{oids_operating}->{jnxOperatingEntry});
}
}
sub get_cache {
my ($self, %options) = @_;
return $self->{results}->{$options{oid_entry}}->{$options{oid_name} . '.' . $options{instance}};
}
sub get_instances {
my ($self, %options) = @_;
my @instances = ();
foreach (keys %{$self->{results}->{$options{oid_entry}}}) {
if (/^$options{oid_name}\.(.*)/) {
push @instances, $1;
}
}
return @instances;
}
sub get_type {
my ($self, %options) = @_;
@ -93,13 +166,38 @@ sub get_type {
$self->{output}->output_add(long_msg => sprintf("Environment type: %s", $self->{env_type}));
}
sub load_components {
my ($self, %options) = @_;
foreach (@{$self->{components_module}}) {
if (/$self->{option_results}->{component}/) {
my $mod_name = $self->{components_path} . "::$_";
centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name,
error_msg => "Cannot load module '$mod_name'.") if ($self->{load_components} == 1);
$self->{loaded} = 1;
}
}
}
sub exec_components {
my ($self, %options) = @_;
foreach (@{$self->{components_module}}) {
if (/$self->{option_results}->{component}/) {
my $mod_name = $self->{components_path} . "::$_";
my $func = $mod_name->can('check');
$func->($self);
}
}
}
1;
__END__
=head1 MODE
Check Hardware (mib-jnx-chassis) (frus, operating).
Check Hardware (JUNIPER-MIB) (frus, operating).
=over 8
@ -139,6 +237,11 @@ Example: --warning='fru-temperature,.*,30'
Set critical threshold for fru temperatures (syntax: type,regexp,threshold)
Example: --critical='fru-temperature,.*,40'
=item B<--reload-cache-time>
Time in minutes before reloading cache file (Default: 180).
Use '-1' to disable cache reload.
=back
=cut

View File

@ -0,0 +1,233 @@
#
# 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::juniper::common::junos::mode::ldpsessionstatus;
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 = "status is '" . $self->{result_values}->{state} . "'";
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_jnxMplsLdpSesState'};
return 0;
}
sub prefix_session_output {
my ($self, %options) = @_;
return "Session between LDP entity '" . $options{instance_value}->{jnxMplsLdpEntityLdpId} . "' and LDP peer '" . $options{instance_value}->{jnxMplsLdpPeerLdpId} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'sessions', type => 1, cb_prefix_output => 'prefix_session_output', message_multiple => 'All sessions status are ok' },
];
$self->{maps_counters}->{sessions} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'jnxMplsLdpSesState' }, { name => 'jnxMplsLdpEntityLdpId' },
{ name => 'jnxMplsLdpPeerLdpId' } ],
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'),
}
},
{ label => 'last-change', set => {
key_values => [ { name => 'jnxMplsLdpSesStateLastChangeHuman' }, { name => 'jnxMplsLdpSesStateLastChange' },
{ name => 'label' } ],
output_template => 'Last change: %s',
perfdatas => [
{ label => 'last_change', value => 'jnxMplsLdpSesStateLastChange_absolute', template => '%d',
min => 0, unit => 's', label_extra_instance => 1, instance_use => 'label_absolute' },
],
}
},
];
}
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-entity:s" => { name => 'filter_entity' },
"filter-peer:s" => { name => 'filter_peer' },
"warning-status:s" => { name => 'warning_status' },
"critical-status:s" => { name => 'critical_status', default => '%{state} !~ /operational/i' },
});
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();
}
my %map_state = (
1 => 'nonexistent',
2 => 'initialized',
3 => 'openrec',
4 => 'opensent',
5 => 'operational',
);
my $mapping = {
jnxMplsLdpSesStateLastChange => { oid => '.1.3.6.1.4.1.2636.3.36.1.3.3.1.1' },
jnxMplsLdpSesState => { oid => '.1.3.6.1.4.1.2636.3.36.1.3.3.1.2', map => \%map_state },
};
my $oid_jnxMplsLdpSessionEntry = '.1.3.6.1.4.1.2636.3.36.1.3.3.1';
sub manage_selection {
my ($self, %options) = @_;
$self->{sessions} = {};
my $results = $options{snmp}->get_table(oid => $oid_jnxMplsLdpSessionEntry, start => $mapping->{jnxMplsLdpSesStateLastChange}->{oid},
end => $mapping->{jnxMplsLdpSesState}->{oid}, nothing_quit => 1);
foreach my $oid (keys %{$results}) {
next if ($oid !~ /^$mapping->{jnxMplsLdpSesState}->{oid}\.(.*)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
$instance =~ /^(\d+\.\d+\.\d+\.\d+)\.(\d+)\.\d+\.\d+\.(\d+\.\d+\.\d+\.\d+)\.(\d+)\.\d+$/;
my $ldp_entity = $1 . ':' . $2;
my $ldp_peer = $3 . ':' . $4;
if (defined($self->{option_results}->{filter_entity}) && $self->{option_results}->{filter_entity} ne '' &&
$ldp_entity !~ /$self->{option_results}->{filter_entity}/) {
$self->{output}->output_add(long_msg => "skipping entity '" . $ldp_entity . "': no matching filter name.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_peer}) && $self->{option_results}->{filter_peer} ne '' &&
$ldp_peer !~ /$self->{option_results}->{filter_peer}/) {
$self->{output}->output_add(long_msg => "skipping peer '" . $ldp_peer . "': no matching filter name.", debug => 1);
next;
}
$self->{sessions}->{$instance} = {
jnxMplsLdpSesStateLastChange => $result->{jnxMplsLdpSesStateLastChange} / 100,
jnxMplsLdpSesStateLastChangeHuman => centreon::plugins::misc::change_seconds(value => $result->{jnxMplsLdpSesStateLastChange} / 100),
jnxMplsLdpSesState => $result->{jnxMplsLdpSesState},
jnxMplsLdpEntityLdpId => $ldp_entity,
jnxMplsLdpPeerLdpId => $ldp_peer,
label => $ldp_entity . "_". $ldp_peer,
}
}
if (scalar(keys %{$self->{sessions}}) <= 0) {
$self->{output}->add_option_msg(short_msg => 'No sessions found.');
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check sessions status between the LDP entities and LDP peers.
=over 8
=item B<--filter-*>
Filter entities and/or peer.
Can be: 'entity', 'peer' (can be a regexp).
=item B<--warning-status>
Set warning threshold for status (Default: '').
Can used special variables like: %{state}
=item B<--critical-status>
Set critical threshold for status (Default: '%{state} !~ /operational/i').
Can used special variables like: %{state}
=item B<--warning-last-change>
Threshold warning in seconds.
=item B<--critical-last-change>
Threshold critical in seconds.
=back
=cut

View File

@ -0,0 +1,256 @@
#
# 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::juniper::common::junos::mode::lspstatus;
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 = "status is '" . $self->{result_values}->{state} . "'";
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_mplsLspState'};
return 0;
}
sub prefix_session_output {
my ($self, %options) = @_;
return "LSP '" . $options{instance_value}->{mplsLspName} . "' [From '" . $options{instance_value}->{mplsLspFrom} . "' to '" . $options{instance_value}->{mplsLspTo} . "'] ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'lsps', type => 1, cb_prefix_output => 'prefix_session_output', message_multiple => 'All LSP status are ok' },
];
$self->{maps_counters}->{lsps} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'mplsLspState' }, { name => 'mplsLspFrom' },
{ name => 'mplsLspTo' }, { name => 'mplsLspName' } ],
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'),
}
},
{ label => 'transition-count', set => {
key_values => [ { name => 'mplsLspInfoTransitions' }, { name => 'mplsLspName' } ],
output_template => 'Transition count: %d',
perfdatas => [
{ label => 'transition_count', value => 'mplsLspInfoTransitions_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'mplsLspName_absolute' },
],
}
},
{ label => 'last-transition', set => {
key_values => [ { name => 'mplsLspInfoLastTransitionHuman' }, { name => 'mplsLspInfoLastTransition' },
{ name => 'mplsLspName' } ],
output_template => 'Last transition: %s',
perfdatas => [
{ label => 'last_transition', value => 'mplsLspInfoLastTransition_absolute', template => '%d',
min => 0, unit => 's', label_extra_instance => 1, instance_use => 'mplsLspName_absolute' },
],
}
},
];
}
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-name:s" => { name => 'filter_name' },
"filter-from:s" => { name => 'filter_from' },
"filter-to:s" => { name => 'filter_to' },
"warning-status:s" => { name => 'warning_status' },
"critical-status:s" => { name => 'critical_status', default => '%{state} !~ /up/i' },
});
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();
}
my %map_state = (
1 => 'unknown',
2 => 'up',
3 => 'down',
4 => 'notInService',
5 => 'backupActive',
);
my $mapping = {
mplsLspState => { oid => '.1.3.6.1.4.1.2636.3.2.5.1.2', map => \%map_state },
mplsLspInfoTransitions => { oid => '.1.3.6.1.4.1.2636.3.2.5.1.8' },
mplsLspInfoLastTransition => { oid => '.1.3.6.1.4.1.2636.3.2.5.1.9' },
mplsLspFrom => { oid => '.1.3.6.1.4.1.2636.3.2.5.1.15' },
mplsLspTo => { oid => '.1.3.6.1.4.1.2636.3.2.5.1.16' },
};
my $oid_mplsLspEntry = '.1.3.6.1.4.1.2636.3.2.5.1';
sub manage_selection {
my ($self, %options) = @_;
$self->{lsps} = {};
my $results = $options{snmp}->get_table(oid => $oid_mplsLspEntry, start => $mapping->{mplsLspState}->{oid},
end => $mapping->{mplsLspTo}->{oid}, nothing_quit => 1);
foreach my $oid (keys %{$results}) {
next if ($oid !~ /^$mapping->{mplsLspState}->{oid}\.(.*)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
my $mplsLspName = '';
foreach (split /\./, $instance) {
$mplsLspName .= chr if ($_ >= 32 && $_ <= 126);
}
$mplsLspName = centreon::plugins::misc::trim($mplsLspName);
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$mplsLspName !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping session '" . $mplsLspName . "': no matching filter name.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_from}) && $self->{option_results}->{filter_from} ne '' &&
$result->{mplsLspFrom} !~ /$self->{option_results}->{filter_from}/) {
$self->{output}->output_add(long_msg => "skipping session '" . $result->{mplsLspFrom} . "': no matching filter from.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_to}) && $self->{option_results}->{filter_to} ne '' &&
$result->{mplsLspTo} !~ /$self->{option_results}->{filter_to}/) {
$self->{output}->output_add(long_msg => "skipping peer '" . $result->{mplsLspTo} . "': no matching filter to.", debug => 1);
next;
}
$self->{lsps}->{$instance} = {
mplsLspName => $mplsLspName,
mplsLspState => $result->{mplsLspState},
mplsLspInfoTransitions => $result->{mplsLspInfoTransitions},
mplsLspInfoLastTransition => $result->{mplsLspInfoLastTransition} / 100,
mplsLspInfoLastTransitionHuman => centreon::plugins::misc::change_seconds(value => $result->{mplsLspInfoLastTransition} / 100),
mplsLspFrom => $result->{mplsLspFrom},
mplsLspTo => $result->{mplsLspTo},
}
}
if (scalar(keys %{$self->{lsps}}) <= 0) {
$self->{output}->add_option_msg(short_msg => 'No entries found.');
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check LSPs (Label Switched Path) status.
=over 8
=item B<--filter-*>
Filter LSPs.
Can be: 'name', 'from', 'to' (can be a regexp).
=item B<--warning-status>
Set warning threshold for status (Default: '').
Can used special variables like: %{state}
=item B<--critical-status>
Set critical threshold for status (Default: '%{state} !~ /up/i').
Can used special variables like: %{state}
=item B<--warning-*>
Threshold warning.
Can be: 'transition-count', 'last-transition' (seconds).
=item B<--critical-*>
Threshold critical.
Can be: 'transition-count', 'last-transition' (seconds).
=back
=cut

View File

@ -0,0 +1,219 @@
#
# 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::juniper::common::junos::mode::rsvpsessionstatus;
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 = "status is '" . $self->{result_values}->{state} . "'";
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_jnxRsvpSessionState'};
return 0;
}
sub prefix_session_output {
my ($self, %options) = @_;
return "Session '" . $options{instance_value}->{jnxRsvpSessionName} . "' [From '" . $options{instance_value}->{jnxRsvpSessionFrom} . "' to '" . $options{instance_value}->{jnxRsvpSessionTo} . "'] ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'sessions', type => 1, cb_prefix_output => 'prefix_session_output', message_multiple => 'All sessions status are ok' },
];
$self->{maps_counters}->{sessions} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'jnxRsvpSessionState' }, { name => 'jnxRsvpSessionFrom' },
{ name => 'jnxRsvpSessionTo' }, { name => 'jnxRsvpSessionName' } ],
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-name:s" => { name => 'filter_name' },
"filter-from:s" => { name => 'filter_from' },
"filter-to:s" => { name => 'filter_to' },
"warning-status:s" => { name => 'warning_status' },
"critical-status:s" => { name => 'critical_status', default => '%{state} !~ /up/i' },
});
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();
}
my %map_state = (
1 => 'up',
2 => 'down',
);
my $mapping = {
jnxRsvpSessionState => { oid => '.1.3.6.1.4.1.2636.3.30.1.1.1.3', map => \%map_state },
jnxRsvpSessionFrom => { oid => '.1.3.6.1.4.1.2636.3.30.1.1.1.4' },
jnxRsvpSessionTo => { oid => '.1.3.6.1.4.1.2636.3.30.1.1.1.5' },
};
my $oid_JnxRsvpSessionEntry = '.1.3.6.1.4.1.2636.3.30.1.1.1';
sub manage_selection {
my ($self, %options) = @_;
$self->{sessions} = {};
my $results = $options{snmp}->get_table(oid => $oid_JnxRsvpSessionEntry, start => $mapping->{jnxRsvpSessionState}->{oid},
end => $mapping->{jnxRsvpSessionTo}->{oid}, nothing_quit => 1);
foreach my $oid (keys %{$results}) {
next if ($oid !~ /^$mapping->{jnxRsvpSessionState}->{oid}\.(.*)/);
my $instance = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance);
my $jnxRsvpSessionName = '';
foreach (split /\./, $instance) {
$jnxRsvpSessionName .= chr if ($_ >= 32 && $_ <= 126);
}
$jnxRsvpSessionName = centreon::plugins::misc::trim($jnxRsvpSessionName);
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$jnxRsvpSessionName !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping session '" . $jnxRsvpSessionName . "': no matching filter name.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_from}) && $self->{option_results}->{filter_from} ne '' &&
$result->{jnxRsvpSessionFrom} !~ /$self->{option_results}->{filter_from}/) {
$self->{output}->output_add(long_msg => "skipping session '" . $result->{jnxRsvpSessionFrom} . "': no matching filter from.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_to}) && $self->{option_results}->{filter_to} ne '' &&
$result->{jnxRsvpSessionTo} !~ /$self->{option_results}->{filter_to}/) {
$self->{output}->output_add(long_msg => "skipping peer '" . $result->{jnxRsvpSessionTo} . "': no matching filter to.", debug => 1);
next;
}
$self->{sessions}->{$instance} = {
jnxRsvpSessionName => $jnxRsvpSessionName,
jnxRsvpSessionState => $result->{jnxRsvpSessionState},
jnxRsvpSessionFrom => $result->{jnxRsvpSessionFrom},
jnxRsvpSessionTo => $result->{jnxRsvpSessionTo},
}
}
if (scalar(keys %{$self->{sessions}}) <= 0) {
$self->{output}->add_option_msg(short_msg => 'No sessions found.');
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check RSVP sessions status.
=over 8
=item B<--filter-*>
Filter sessions.
Can be: 'name', 'from', 'to' (can be a regexp).
=item B<--warning-status>
Set warning threshold for status (Default: '').
Can used special variables like: %{state}
=item B<--critical-status>
Set critical threshold for status (Default: '%{state} !~ /up/i').
Can used special variables like: %{state}
=back
=cut

View File

@ -31,12 +31,15 @@ sub new {
$self->{version} = '1.0';
%{$self->{modes}} = (
'hardware' => 'network::juniper::common::junos::mode::hardware',
'cpu-routing' => 'network::juniper::common::junos::mode::cpurouting', # routing engine
'memory-routing' => 'network::juniper::common::junos::mode::memoryrouting', # routing engine
'hardware' => 'network::juniper::common::junos::mode::hardware',
'interfaces' => 'snmp_standard::mode::interfaces',
'ldp-session-status' => 'network::juniper::common::junos::mode::ldpsessionstatus',
'lsp-status' => 'network::juniper::common::junos::mode::lspstatus',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'list-storages' => 'snmp_standard::mode::liststorages',
'memory-routing' => 'network::juniper::common::junos::mode::memoryrouting', # routing engine
'rsvp-session-status' => 'network::juniper::common::junos::mode::rsvpsessionstatus',
'storage' => 'snmp_standard::mode::storage',
);

View File

@ -90,22 +90,24 @@ sub run {
my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5';
my $oid_hrStorageUsed = '.1.3.6.1.2.1.25.2.3.1.6';
my $physicalSize = 0;
my $physicalUsed = 0;
my ($physicalSize, $physicalUsed, $physicalUnits) = (0, 0, 0);
if (defined($self->{option_results}->{real_swap})) {
$self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed],
instances => [$self->{physical_memory_id}]);
$result = $self->{snmp}->get_leef();
$physicalSize = $result->{$oid_hrStorageSize . "." . $self->{physical_memory_id}};
$physicalUsed = $result->{$oid_hrStorageUsed . "." . $self->{physical_memory_id}};
$physicalUnits = $result->{$oid_hrStorageAllocationUnits . "." . $self->{physical_memory_id}};
}
$self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed],
instances => [$self->{swap_memory_id}]);
$result = $self->{snmp}->get_leef();
my $swap_used = ($result->{$oid_hrStorageUsed . "." . $self->{swap_memory_id}} - $physicalUsed) * $result->{$oid_hrStorageAllocationUnits . "." . $self->{swap_memory_id}};
my $total_size = ($result->{$oid_hrStorageSize . "." . $self->{swap_memory_id}} - $physicalSize) * $result->{$oid_hrStorageAllocationUnits . "." . $self->{swap_memory_id}};
my $swap_used = ($result->{$oid_hrStorageUsed . "." . $self->{swap_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{swap_memory_id}})
- ($physicalUsed * $physicalUnits);
my $total_size = ($result->{$oid_hrStorageSize . "." . $self->{swap_memory_id}} * $result->{$oid_hrStorageAllocationUnits . "." . $self->{swap_memory_id}})
- ($physicalSize * $physicalUnits);
my $prct_used = $swap_used * 100 / $total_size;
my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
@ -150,8 +152,8 @@ Threshold critical in percent.
=item B<--real-swap>
Use this option to remove physical
memory from Windows SNMP swap values.
Use this option to remove physical memory from Windows SNMP swap values.
Using that option can give wrong values (incoherent or negative).
=back

View File

@ -119,7 +119,7 @@ sub new {
sub change_macros {
my ($self, %options) = @_;
foreach ('warning_status', 'critical_status') {
foreach (('warning_status', 'critical_status')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g;
}
@ -130,6 +130,10 @@ sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{option_results}->{remote} = 1;
}
$instance_mode = $self;
$self->change_macros();
}

View File

@ -129,6 +129,10 @@ sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{option_results}->{remote} = 1;
}
$instance_mode = $self;
$self->change_macros();
}

View File

@ -119,7 +119,7 @@ sub new {
sub change_macros {
my ($self, %options) = @_;
foreach ('warning_status', 'critical_status') {
foreach (('warning_status', 'critical_status')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g;
}
@ -130,6 +130,10 @@ sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{option_results}->{remote} = 1;
}
$instance_mode = $self;
$self->change_macros();
}

View File

@ -118,7 +118,7 @@ sub new {
sub change_macros {
my ($self, %options) = @_;
foreach ('warning_status', 'critical_status') {
foreach (('warning_status', 'critical_status')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g;
}
@ -129,6 +129,10 @@ sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{option_results}->{remote} = 1;
}
$instance_mode = $self;
$self->change_macros();
}

View File

@ -120,7 +120,7 @@ sub new {
sub change_macros {
my ($self, %options) = @_;
foreach ('warning_status', 'critical_status') {
foreach (('warning_status', 'critical_status')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g;
}
@ -131,6 +131,10 @@ sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{option_results}->{remote} = 1;
}
$instance_mode = $self;
$self->change_macros();
}

View File

@ -33,8 +33,8 @@ sub new {
%{$self->{modes}} = (
'compaction' => 'storage::quantum::dxi::ssh::mode::compaction',
'disk-usage' => 'storage::quantum::dxi::ssh::mode::diskusage',
'hostbus-adapter-status' => 'storage::quantum::dxi::ssh::mode::hostbusadapterstatus',
'health' => 'storage::quantum::dxi::ssh::mode::health',
'hostbus-adapter-status' => 'storage::quantum::dxi::ssh::mode::hostbusadapterstatus',
'memory' => 'storage::quantum::dxi::ssh::mode::memory',
'network' => 'storage::quantum::dxi::ssh::mode::network',
'reclamation' => 'storage::quantum::dxi::ssh::mode::reclamation',