(plugin) apps::thales::mistral::vs9::restapi - add clusters mode (#4093)

This commit is contained in:
qgarnier 2022-12-13 11:25:00 +00:00 committed by GitHub
parent f12c0e62a4
commit 9fc4b4ba9b
6 changed files with 551 additions and 22 deletions

View File

@ -227,6 +227,26 @@ sub request_api {
return $decoded; return $decoded;
} }
sub get_clusters {
my ($self, %options) = @_;
my $has_cache_file = $self->{cache}->read(statefile => 'thales_mistral_clusters_' . md5_hex($self->get_connection_info() . '_' . $self->{api_username}));
my $updated = $self->{cache}->get(name => 'updated');
my $clusters = $self->{cache}->get(name => 'clusters');
if ($has_cache_file == 0 || !defined($updated) || ((time() - $updated) > (($self->{option_results}->{reload_cache_time} * 60)))) {
my $cache = { updated => time() };
my $result = $self->request_api(
endpoint => '/clusters'
);
$clusters = $result;
$cache->{clusters} = $clusters;
$self->{cache}->write(data => $cache);
}
return $clusters;
}
sub get_gateway_inventory { sub get_gateway_inventory {
my ($self, %options) = @_; my ($self, %options) = @_;

View File

@ -0,0 +1,333 @@
#
# Copyright 2022 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 apps::thales::mistral::vs9::restapi::mode::clusters;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use DateTime;
use POSIX;
use centreon::plugins::misc;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
sub custom_information_output {
my ($self, %options) = @_;
return sprintf(
'virtual ip: %s, timeToSwitch: %s s',
$self->{result_values}->{virtualIp},
$self->{result_values}->{timeToSwitch}
);
}
sub custom_cluster_status_output {
my ($self, %options) = @_;
return sprintf(
'status: %s, available for switching: %s',
$self->{result_values}->{gatewaysClusterStatus},
$self->{result_values}->{availableForSwitching}
);
}
sub custom_member_status_output {
my ($self, %options) = @_;
return sprintf(
'connected status: %s [role: %s]',
$self->{result_values}->{connectedStatus},
$self->{result_values}->{role}
);
}
sub custom_contact_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{time_contact_unit} },
unit => $self->{instance_mode}->{option_results}->{time_contact_unit},
instances => [$self->{result_values}->{clusterName}, $self->{result_values}->{memberName}],
value => floor($self->{result_values}->{contact_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{time_contact_unit} }),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0
);
}
sub custom_contact_threshold {
my ($self, %options) = @_;
return $self->{perfdata}->threshold_check(
value => floor($self->{result_values}->{contact_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{time_contact_unit} }),
threshold => [
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' },
{ label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' }
]
);
}
sub cluster_long_output {
my ($self, %options) = @_;
return sprintf(
"checking cluster '%s'",
$options{instance_value}->{clusterName}
);
}
sub prefix_cluster_output {
my ($self, %options) = @_;
return sprintf(
"cluster '%s' ",
$options{instance_value}->{clusterName}
);
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Number of clusters ';
}
sub prefix_member_output {
my ($self, %options) = @_;
return sprintf(
"member '%s' ",
$options{instance_value}->{memberName}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' },
{
name => 'clusters', type => 3, cb_prefix_output => 'prefix_cluster_output', cb_long_output => 'cluster_long_output', indent_long_output => ' ', message_multiple => 'All clusters are ok',
group => [
{ name => 'information', type => 0, skipped_code => { -10 => 1 } },
{ name => 'status', type => 0, skipped_code => { -10 => 1 } },
{ name => 'members', type => 1, cb_prefix_output => 'prefix_member_output', message_multiple => 'members are ok', display_long => 1, skipped_code => { -10 => 1 } }
]
}
];
$self->{maps_counters}->{global} = [
{ label => 'clusters-detected', display_ok => 0, nlabel => 'clusters.detected.count', set => {
key_values => [ { name => 'detected' } ],
output_template => 'detected: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
}
];
$self->{maps_counters}->{information} = [
{
label => 'cluster-information',
type => 2,
set => {
key_values => [ { name => 'virtualIp' }, { name => 'timeToSwitch' } ],
closure_custom_output => $self->can('custom_information_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
$self->{maps_counters}->{status} = [
{
label => 'cluster-status',
type => 2,
warning_default => '%{gatewaysClusterStatus} =~ /HAC_FAILOVER/i',
critical_default => '%{gatewaysClusterStatus} =~ /HAC_FAILURE|HAC_DOWN|HAC_BACKUP_FAILURE/i',
set => {
key_values => [ { name => 'gatewaysClusterStatus' }, { name => 'availableForSwitching' }, { name => 'clusterName' } ],
closure_custom_output => $self->can('custom_cluster_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
$self->{maps_counters}->{members} = [
{
label => 'member-status',
type => 2,
set => {
key_values => [ { name => 'role' }, { name => 'connectedStatus' }, { name => 'clusterName' }, { name => 'memberName' } ],
closure_custom_output => $self->can('custom_member_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'member-contact-last-time', nlabel => 'member.contact.last.time', set => {
key_values => [ { name => 'contact_seconds' }, { name => 'contact_human' }, { name => 'clusterName' }, { name => 'memberName' } ],
output_template => 'last contact: %s',
output_use => 'contact_human',
closure_custom_perfdata => $self->can('custom_contact_perfdata'),
closure_custom_threshold_check => $self->can('custom_contact_threshold')
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'filter-cluster-name:s' => { name => 'filter_cluster_name' },
'time-contact-unit:s' => { name => 'time_contact_unit', default => 's' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if ($self->{option_results}->{time_contact_unit} eq '' || !defined($unitdiv->{$self->{option_results}->{time_contact_unit}})) {
$self->{option_results}->{time_contact_unit} = 's';
}
}
sub manage_selection {
my ($self, %options) = @_;
my $clusters = $options{custom}->get_clusters();
$self->{global} = { detected => 0 };
$self->{clusters} = {};
foreach my $cluster (@$clusters) {
next if (defined($self->{option_results}->{filter_cluster_name}) && $self->{option_results}->{filter_cluster_name} ne '' &&
$cluster->{name} !~ /$self->{option_results}->{filter_cluster_name}/);
$self->{global}->{detected}++;
$self->{clusters}->{ $cluster->{name} } = {
clusterName => $cluster->{name},
information => {
virtualIp => $cluster->{virtualIp} . '/' . $cluster->{virtualNetmask},
timeToSwitch => $cluster->{timeToSwitch}
},
status => {
clusterName => $cluster->{name},
gatewaysClusterStatus => $cluster->{gatewaysClusterStatus},
availableForSwitching => $cluster->{availableForSwitching} =~ /true|1/i ? 'yes' : 'no'
},
members => {}
};
foreach ('master', 'backup') {
$self->{clusters}->{ $cluster->{name} }->{members}->{ $cluster->{$_ . 'Origin'}->{name} } = {
clusterName => $cluster->{name},
memberName => $cluster->{$_ . 'Origin'}->{name},
connectedStatus => lc($cluster->{$_ . 'OriginStatus'}->{connectedStatus}),
role => $_
};
if ($cluster->{$_ . 'OriginStatus'}->{lastCheck} =~ /^\s*(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.\d+([+-].*)$/) {
my $dt = DateTime->new(
year => $1,
month => $2,
day => $3,
hour => $4,
minute => $5,
second => $6,
time_zone => $7
);
$self->{clusters}->{ $cluster->{name} }->{members}->{ $cluster->{$_ . 'Origin'}->{name} }->{contact_seconds} =
time() - $dt->epoch();
$self->{clusters}->{ $cluster->{name} }->{members}->{ $cluster->{$_ . 'Origin'}->{name} }->{contact_human} = centreon::plugins::misc::change_seconds(
value => $self->{clusters}->{ $cluster->{name} }->{members}->{ $cluster->{$_ . 'Origin'}->{name} }->{contact_seconds}
);
}
}
}
}
1;
__END__
=head1 MODE
Check clusters.
=over 8
=item B<--filter-cluster-name>
Filter clusters by name.
=item B<--unknown-cluster-status>
Set unknown threshold for status.
Can used special variables like: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName}
=item B<--warning-cluster-status>
Set warning threshold for status (Default: '%{gatewaysClusterStatus} =~ /HAC_FAILOVER/i').
Can used special variables like: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName}
=item B<--critical-cluster-status>
Set critical threshold for status (Default: '%{gatewaysClusterStatus} =~ /HAC_FAILURE|HAC_DOWN|HAC_BACKUP_FAILURE/i').
Can used special variables like: %{gatewaysClusterStatus}, %{availableForSwitching}, %{clusterName}
=item B<--unknown-member-status>
Set unknown threshold for status.
Can used special variables like: %{connectedStatus}, %{role}, %{memberName}
=item B<--warning-member-status>
Set warning threshold for status.
Can used special variables like: %{connectedStatus}, %{role}, %{memberName}
=item B<--critical-member-status>
Set critical threshold for status.
Can used special variables like: %{connectedStatus}, %{role}, %{memberName}
=item B<--time-contact-unit>
Select the time unit for contact threshold. May be 's' for seconds, 'm' for minutes,
'h' for hours, 'd' for days, 'w' for weeks. Default is seconds.
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'clusters-detected', 'member-contact-last-time'.
=back
=cut

View File

@ -33,13 +33,27 @@ use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 }; my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' }; my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
sub custom_certificate_status_output {
my ($self, %options) = @_;
return sprintf(
'revoked: %s',
$self->{result_values}->{revoked}
);
}
sub custom_certificate_expires_perfdata { sub custom_certificate_expires_perfdata {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->{output}->perfdata_add( $self->{output}->perfdata_add(
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{time_certificate_unit} }, nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{time_certificate_unit} },
unit => $self->{instance_mode}->{option_results}->{time_certificate_unit}, unit => $self->{instance_mode}->{option_results}->{time_certificate_unit},
instances => [$self->{result_values}->{sn}, $self->{result_values}->{name}], instances => [
$self->{result_values}->{sn},
$self->{result_values}->{certSn},
$self->{result_values}->{subjectCommonName},
$self->{result_values}->{issuerCommonName}
],
value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{time_certificate_unit} }), value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{time_certificate_unit} }),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
@ -110,9 +124,10 @@ sub custom_mistral_version_output {
my ($self, %options) = @_; my ($self, %options) = @_;
return sprintf( return sprintf(
'firmware version: %s (current) %s (other)', 'firmware version: %s (current) %s (other), configurationId: %s',
$self->{result_values}->{firmwareCurrentVersion}, $self->{result_values}->{firmwareCurrentVersion},
$self->{result_values}->{firmwareOtherVersion} $self->{result_values}->{firmwareOtherVersion},
$self->{result_values}->{configurationId}
); );
} }
@ -281,8 +296,11 @@ sub prefix_certificate_output {
my ($self, %options) = @_; my ($self, %options) = @_;
return sprintf( return sprintf(
"certificate '%s' ", "certificate '%s' [subject: %s, issuer: %s, usages: %s] ",
$options{instance_value}->{name} $options{instance_value}->{certSn},
$options{instance_value}->{subjectCommonName},
$options{instance_value}->{issuerCommonName},
$options{instance_value}->{usages}
); );
} }
@ -364,7 +382,7 @@ sub set_counters {
label => 'mistral-version', label => 'mistral-version',
type => 2, type => 2,
set => { set => {
key_values => [ { name => 'firmwareCurrentVersion' }, { name => 'firmwareOtherVersion' } ], key_values => [ { name => 'firmwareCurrentVersion' }, { name => 'firmwareOtherVersion' }, { name => 'configurationId' } ],
closure_custom_output => $self->can('custom_mistral_version_output'), closure_custom_output => $self->can('custom_mistral_version_output'),
closure_custom_perfdata => sub { return 0; }, closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng closure_custom_threshold_check => \&catalog_status_threshold_ng
@ -482,8 +500,26 @@ sub set_counters {
]; ];
$self->{maps_counters}->{certificates} = [ $self->{maps_counters}->{certificates} = [
{
label => 'certificate-status',
type => 2,
set => {
key_values => [
{ name => 'revoked' },
{ name => 'certSn' }, { name => 'subjectCommonName' }, { name => 'issuerCommonName' },
{ name => 'sn' }
],
closure_custom_output => $self->can('custom_certificate_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'certificate-expires', nlabel => 'certificate.expires', set => { { label => 'certificate-expires', nlabel => 'certificate.expires', set => {
key_values => [ { name => 'expires_seconds' }, { name => 'expires_human' }, { name => 'name' }, { name => 'sn' } ], key_values => [
{ name => 'expires_seconds' }, { name => 'expires_human' },
{ name => 'certSn' }, { name => 'subjectCommonName' }, { name => 'issuerCommonName' },
{ name => 'sn' }
],
output_template => 'expires in %s', output_template => 'expires in %s',
output_use => 'expires_human', output_use => 'expires_human',
closure_custom_perfdata => $self->can('custom_certificate_expires_perfdata'), closure_custom_perfdata => $self->can('custom_certificate_expires_perfdata'),
@ -562,6 +598,7 @@ sub new {
$options{options}->add_options(arguments => { $options{options}->add_options(arguments => {
'filter-id:s' => { name => 'filter_id' }, 'filter-id:s' => { name => 'filter_id' },
'filter-sn:s' => { name => 'filter_sn' }, 'filter-sn:s' => { name => 'filter_sn' },
'filter-cert-revoked' => { name => 'filter_cert_revoked' },
'add-interfaces' => { name => 'add_interfaces' }, 'add-interfaces' => { name => 'add_interfaces' },
'add-status' => { name => 'add_status' }, 'add-status' => { name => 'add_status' },
'add-system' => { name => 'add_system' }, 'add-system' => { name => 'add_system' },
@ -722,6 +759,7 @@ sub add_mistral {
sn => $options{device}->{serialNumber}, sn => $options{device}->{serialNumber},
firmwareCurrentVersion => $mistral->{firmwareCurrent}->{version}, firmwareCurrentVersion => $mistral->{firmwareCurrent}->{version},
firmwareOtherVersion => $mistral->{firmwareOther}->{version}, firmwareOtherVersion => $mistral->{firmwareOther}->{version},
configurationId => $mistral->{configurationId},
operatingState => lc($mistral->{operatingState}), operatingState => lc($mistral->{operatingState}),
temperature => $mistral->{temperature} temperature => $mistral->{temperature}
}; };
@ -751,9 +789,17 @@ sub add_certificates {
second => $6, second => $6,
time_zone => $7 time_zone => $7
); );
my $revoked = $cert->{revoked} =~ /true|1/i ? 'yes' : 'no';
next if (defined($self->{option_results}->{filter_cert_revoked}) && $revoked eq 'yes');
$self->{devices}->{ $options{device}->{id} }->{certificates}->{ $cert->{gwCertificateName} } = { $self->{devices}->{ $options{device}->{id} }->{certificates}->{ $cert->{gwCertificateName} } = {
sn => $options{device}->{serialNumber}, sn => $options{device}->{serialNumber},
name => $cert->{gwCertificateName}, certSn => $cert->{serialNumber},
subjectCommonName => $cert->{subjectCommonName},
issuerCommonName => defined($cert->{issuerCommonName}) ? $cert->{issuerCommonName} : '',
usages => join(' ', @{$cert->{usages}}),
revoked => $revoked,
expires_seconds => $dt->epoch() - time() expires_seconds => $dt->epoch() - time()
}; };
$self->{devices}->{ $options{device}->{id} }->{certificates}->{ $cert->{gwCertificateName} }->{expires_seconds} = 0 $self->{devices}->{ $options{device}->{id} }->{certificates}->{ $cert->{gwCertificateName} }->{expires_seconds} = 0
@ -880,6 +926,10 @@ Filter devices by id.
Filter devices by serial number. Filter devices by serial number.
=item B<--filter-cert-revoked>
Skip revoked certificates.
=item B<--add-status> =item B<--add-status>
Check connection status. Check connection status.
@ -904,6 +954,21 @@ Check certificates.
Check tunnels. Check tunnels.
=item B<--unknown-certificate-status>
Set unknown threshold for status.
Can used special variables like: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName}
=item B<--warning-certificate-status>
Set warning threshold for status.
Can used special variables like: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName}
=item B<--critical-certificate-status>
Set critical threshold for status.
Can used special variables like: %{revoked}, %{sn}, %{certSn}, %{subjectCommonName}, %{issuerCommonName}
=item B<--unknown-connection-status> =item B<--unknown-connection-status>
Set unknown threshold for status (Default: '%{connectionStatus} =~ /unknown/i'). Set unknown threshold for status (Default: '%{connectionStatus} =~ /unknown/i').

View File

@ -46,7 +46,7 @@ sub check_options {
if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') { if (!defined($self->{option_results}->{resource_type}) || $self->{option_results}->{resource_type} eq '') {
$self->{option_results}->{resource_type} = 'device'; $self->{option_results}->{resource_type} = 'device';
} }
if ($self->{option_results}->{resource_type} !~ /^device$/) { if ($self->{option_results}->{resource_type} !~ /^device|mmc$/) {
$self->{output}->add_option_msg(short_msg => 'unknown resource type'); $self->{output}->add_option_msg(short_msg => 'unknown resource type');
$self->{output}->option_exit(); $self->{output}->option_exit();
} }
@ -86,7 +86,8 @@ sub discovery_device {
$entry->{gateway_name} = defined($device->{gatewayConf}) ? $device->{gatewayConf}->{name} : ''; $entry->{gateway_name} = defined($device->{gatewayConf}) ? $device->{gatewayConf}->{name} : '';
$entry->{gateway_responder_only} = ''; $entry->{gateway_responder_only} = '';
$entry->{gateway_responder_only} = $device->{gatewayConf}->{responderOnly} =~ /true|1/i ? 'yes' : 'no' if (defined($device->{gatewayConf})); $entry->{gateway_responder_only} = $device->{gatewayConf}->{responderOnly} =~ /true|1/i ? 'yes' : 'no'
if (defined($device->{gatewayConf}) && defined($device->{gatewayConf}->{responderOnly}));
$entry->{gateway_administration_ip} = defined($device->{gatewayConf}) ? $device->{gatewayConf}->{administrationIp} : ''; $entry->{gateway_administration_ip} = defined($device->{gatewayConf}) ? $device->{gatewayConf}->{administrationIp} : '';
$entry->{gateway_active} = ''; $entry->{gateway_active} = '';
$entry->{gateway_active} = $device->{gatewayConf}->{active} =~ /true|1/i ? 'yes' : 'no' if (defined($device->{gatewayConf})); $entry->{gateway_active} = $device->{gatewayConf}->{active} =~ /true|1/i ? 'yes' : 'no' if (defined($device->{gatewayConf}));
@ -95,6 +96,34 @@ sub discovery_device {
$entry->{gateway_private_address} = defined($device->{gatewayConf}) ? $device->{gatewayConf}->{privateAddress}->{address} : ''; $entry->{gateway_private_address} = defined($device->{gatewayConf}) ? $device->{gatewayConf}->{privateAddress}->{address} : '';
$entry->{gateway_private_address_netmask} = defined($device->{gatewayConf}) ? $device->{gatewayConf}->{privateAddress}->{netmask} : ''; $entry->{gateway_private_address_netmask} = defined($device->{gatewayConf}) ? $device->{gatewayConf}->{privateAddress}->{netmask} : '';
$entry->{gateway_blackIpRemote_address} = '';
$entry->{gateway_blackIpRemote_address_netmask} = '';
if (defined($device->{gatewayConf}) && defined($device->{gatewayConf}->{gatewayBlackIpRemote})) {
$entry->{gateway_blackIpRemote_address} = $device->{gatewayConf}->{gatewayBlackIpRemote}->{address};
$entry->{gateway_blackIpRemote_address_netmask} = $device->{gatewayConf}->{gatewayBlackIpRemote}->{netmask};
}
push @$disco_data, $entry;
}
return $disco_data;
}
sub discovery_mmc {
my ($self, %options) = @_;
my $mmcs = $options{custom}->request_api(
endpoint => '/managementCenters',
get_param => ['projection=managementCenterSmall']
);
my $disco_data = [];
foreach my $mmc (@{$mmcs->{content}}) {
my $entry = {};
$entry->{id} = $mmc->{id};
$entry->{name} = $mmc->{name};
$entry->{ip} = $mmc->{ipAddress};
push @$disco_data, $entry; push @$disco_data, $entry;
} }
@ -112,6 +141,10 @@ sub run {
$results = $self->discovery_device( $results = $self->discovery_device(
custom => $options{custom} custom => $options{custom}
); );
} elsif ($self->{option_results}->{resource_type} eq 'mmc') {
$results = $self->discovery_mmc(
custom => $options{custom}
);
} }
$disco_stats->{end_time} = time(); $disco_stats->{end_time} = time();
@ -148,7 +181,7 @@ Resources discovery.
=item B<--resource-type> =item B<--resource-type>
Choose the type of resources to discover (Can be: 'device'). Choose the type of resources to discover (Can be: 'device', 'mmc').
=back =back

View File

@ -27,17 +27,32 @@ use warnings;
use DateTime; use DateTime;
use POSIX; use POSIX;
use centreon::plugins::misc; use centreon::plugins::misc;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 }; my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 };
my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' }; my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' };
sub custom_certificate_status_output {
my ($self, %options) = @_;
return sprintf(
'active: %s [revoked: %s]',
$self->{result_values}->{active},
$self->{result_values}->{revoked}
);
}
sub custom_certificate_expires_perfdata { sub custom_certificate_expires_perfdata {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->{output}->perfdata_add( $self->{output}->perfdata_add(
nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{time_certificate_unit} }, nlabel => $self->{nlabel} . '.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{time_certificate_unit} },
unit => $self->{instance_mode}->{option_results}->{time_certificate_unit}, unit => $self->{instance_mode}->{option_results}->{time_certificate_unit},
instances => $self->{result_values}->{name}, instances => [
$self->{result_values}->{sn},
$self->{result_values}->{subjectCommonName},
$self->{result_values}->{issuerCommonName}
],
value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{time_certificate_unit} }), value => floor($self->{result_values}->{expires_seconds} / $unitdiv->{ $self->{instance_mode}->{option_results}->{time_certificate_unit} }),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
@ -62,8 +77,11 @@ sub prefix_certificate_output {
my ($self, %options) = @_; my ($self, %options) = @_;
return sprintf( return sprintf(
"certificate '%s' ", "certificate '%s' [subject: %s, issuer: %s, usages: %s] ",
$options{instance_value}->{name} $options{instance_value}->{sn},
$options{instance_value}->{subjectCommonName},
$options{instance_value}->{issuerCommonName},
$options{instance_value}->{usages}
); );
} }
@ -75,8 +93,24 @@ sub set_counters {
]; ];
$self->{maps_counters}->{certificates} = [ $self->{maps_counters}->{certificates} = [
{
label => 'certificate-status',
type => 2,
set => {
key_values => [
{ name => 'active' }, { name => 'revoked' },
{ name => 'sn' }, { name => 'subjectCommonName' }, { name => 'issuerCommonName' }
],
closure_custom_output => $self->can('custom_certificate_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{ label => 'certificate-expires', nlabel => 'certificate.expires', set => { { label => 'certificate-expires', nlabel => 'certificate.expires', set => {
key_values => [ { name => 'expires_seconds' }, { name => 'expires_human' }, { name => 'name' } ], key_values => [
{ name => 'expires_seconds' }, { name => 'expires_human' },
{ name => 'sn' }, { name => 'subjectCommonName' }, { name => 'issuerCommonName' }
],
output_template => 'expires in %s', output_template => 'expires in %s',
output_use => 'expires_human', output_use => 'expires_human',
closure_custom_perfdata => $self->can('custom_certificate_expires_perfdata'), closure_custom_perfdata => $self->can('custom_certificate_expires_perfdata'),
@ -92,7 +126,9 @@ sub new {
bless $self, $class; bless $self, $class;
$options{options}->add_options(arguments => { $options{options}->add_options(arguments => {
'time-certificate-unit:s' => { name => 'time_certificate_unit', default => 's' } 'time-certificate-unit:s' => { name => 'time_certificate_unit', default => 's' },
'filter-cert-inactive' => { name => 'filter_cert_inactive' },
'filter-cert-revoked' => { name => 'filter_cert_revoked' }
}); });
return $self; return $self;
@ -121,14 +157,32 @@ sub add_certificate {
second => $6, second => $6,
time_zone => $7 time_zone => $7
); );
$self->{certificates}->{ $options{cert}->{subjectCommonName} } = {
name => $options{cert}->{subjectCommonName}, my $revoked;
if (defined($options{cert}->{revoked})) {
$revoked = $options{cert}->{revoked} =~ /true|1/i ? 'yes' : 'no';
return if (defined($self->{option_results}->{filter_cert_revoked}) && $revoked eq 'yes');
}
my $active;
if (defined($options{cert}->{active})) {
$active = $options{cert}->{active} =~ /true|1/i ? 'yes' : 'no';
return if (defined($self->{option_results}->{filter_cert_inactive}) && $active eq 'no');
}
$self->{certificates}->{ $options{cert}->{serialNumber} } = {
sn => $options{cert}->{serialNumber},
subjectCommonName => $options{cert}->{subjectCommonName},
issuerCommonName => defined($options{cert}->{issuerCommonName}) ? $options{cert}->{issuerCommonName} : '',
usages => join(' ', @{$options{cert}->{usages}}),
active => $active,
revoked => $revoked,
expires_seconds => $dt->epoch() - time() expires_seconds => $dt->epoch() - time()
}; };
$self->{certificates}->{ $options{cert}->{subjectCommonName} }->{expires_seconds} = 0 $self->{certificates}->{ $options{cert}->{serialNumber} }->{expires_seconds} = 0
if ($self->{certificates}->{ $options{cert}->{subjectCommonName} }->{expires_seconds} < 0); if ($self->{certificates}->{ $options{cert}->{serialNumber} }->{expires_seconds} < 0);
$self->{certificates}->{ $options{cert}->{subjectCommonName} }->{expires_human} = centreon::plugins::misc::change_seconds( $self->{certificates}->{ $options{cert}->{serialNumber} }->{expires_human} = centreon::plugins::misc::change_seconds(
value => $self->{certificates}->{ $options{cert}->{subjectCommonName} }->{expires_seconds} value => $self->{certificates}->{ $options{cert}->{serialNumber} }->{expires_seconds}
); );
} }
@ -164,6 +218,29 @@ Check certificates.
Select the time unit for certificate threshold. May be 's' for seconds, 'm' for minutes, Select the time unit for certificate threshold. May be 's' for seconds, 'm' for minutes,
'h' for hours, 'd' for days, 'w' for weeks. Default is seconds. 'h' for hours, 'd' for days, 'w' for weeks. Default is seconds.
=item B<--filter-cert-inactive>
Skip inactive certificates.
=item B<--filter-cert-revoked>
Skip revoked certificates.
=item B<--unknown-certificate-status>
Set unknown threshold for status.
Can used special variables like: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName}
=item B<--warning-certificate-status>
Set warning threshold for status.
Can used special variables like: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName}
=item B<--critical-certificate-status>
Set critical threshold for status.
Can used special variables like: %{active}, %{revoked}, %{sn}, %{subjectCommonName}, %{issuerCommonName}
=item B<--warning-*> B<--critical-*> =item B<--warning-*> B<--critical-*>
Thresholds. Thresholds.

View File

@ -30,6 +30,7 @@ sub new {
bless $self, $class; bless $self, $class;
$self->{modes} = { $self->{modes} = {
'clusters' => 'apps::thales::mistral::vs9::restapi::mode::clusters',
'devices' => 'apps::thales::mistral::vs9::restapi::mode::devices', 'devices' => 'apps::thales::mistral::vs9::restapi::mode::devices',
'discovery' => 'apps::thales::mistral::vs9::restapi::mode::discovery', 'discovery' => 'apps::thales::mistral::vs9::restapi::mode::discovery',
'mmc-certificates' => 'apps::thales::mistral::vs9::restapi::mode::mmccertificates', 'mmc-certificates' => 'apps::thales::mistral::vs9::restapi::mode::mmccertificates',