(plugin) cloud::aws::directconnect - new (#4382)

This commit is contained in:
qgarnier 2023-04-24 14:04:41 +02:00 committed by David Boucher
parent 55259e0251
commit 8d86eb38bd
12 changed files with 1020 additions and 13 deletions

View File

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

View File

@ -0,0 +1,10 @@
{
"pkg_name": "centreon-plugin-Cloud-Aws-Directconnect-Api",
"pkg_summary": "Centreon Plugin to monitor Amazon AWS Direct Connect service using Cloudwatch API",
"plugin_name": "centreon_aws_directconnect_api.pl",
"files": [
"centreon/plugins/script_custom.pm",
"cloud/aws/custom/",
"cloud/aws/directconnect/"
]
}

View File

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

View File

@ -914,6 +914,68 @@ sub elasticache_describe_cache_clusters {
return $results;
}
sub directconnect_describe_connections_set_cmd {
my ($self, %options) = @_;
return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '');
my $cmd_options = "directconnect describe-connections --region $self->{option_results}->{region} --output json";
$cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne '');
$cmd_options .= " --no-verify-ssl 2>/dev/null" if (defined($self->{option_results}->{skip_ssl_check}));
return $cmd_options;
}
sub directconnect_describe_connections {
my ($self, %options) = @_;
my $cmd_options = $self->directconnect_describe_connections_set_cmd(%options);
my $raw_results = $self->execute(cmd_options => $cmd_options);
my $results = {};
foreach (@{$raw_results->{connections}}) {
$results->{ $_->{connectionId} } = {
name => $_->{connectionName},
state => $_->{connectionState},
bandwidth => $_->{bandwidth}
};
}
return $results;
}
sub directconnect_describe_virtual_interfaces_set_cmd {
my ($self, %options) = @_;
return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '');
my $cmd_options = "directconnect describe-virtual-interfaces --region $self->{option_results}->{region} --output json";
$cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne '');
$cmd_options .= " --no-verify-ssl 2>/dev/null" if (defined($self->{option_results}->{skip_ssl_check}));
return $cmd_options;
}
sub directconnect_describe_virtual_interfaces {
my ($self, %options) = @_;
my $cmd_options = $self->directconnect_describe_virtual_interfaces_set_cmd(%options);
my $raw_results = $self->execute(cmd_options => $cmd_options);
my $results = {};
foreach (@{$raw_results->{virtualInterfaces}}) {
$results->{ $_->{virtualInterfaceId} } = {
name => $_->{virtualInterfaceName},
state => $_->{virtualInterfaceState},
type => $_->{virtualInterfaceType},
vlan => $_->{vlan},
connectionId => $_->{connectionId}
};
}
return $results;
}
1;
__END__

View File

@ -71,18 +71,25 @@ sub custom_metric_perfdata {
sub custom_metric_output {
my ($self, %options) = @_;
my $msg = '';
my $extra_unit = '';
my $metric_label = 'value';
if (defined($self->{instance_mode}->{option_results}->{per_sec})) {
my ($value, $unit) = ($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit} eq 'B') ?
$self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}) :
($self->{result_values}->{value_per_sec}, $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit});
$msg = sprintf("%s: %.2f %s", $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{output}, $value, $unit . '/s');
} else {
my ($value, $unit) = ($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit} eq 'B') ?
$self->{perfdata}->change_bytes(value => $self->{result_values}->{value}) :
($self->{result_values}->{value}, $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit});
$msg = sprintf("%s: %.2f %s", $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{output}, $value, $unit);
$metric_label = 'value_per_sec';
$extra_unit = '/s';
}
my ($value, $unit);
if ($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit} eq 'B') {
($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{$metric_label});
} elsif ($self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit} eq 'bps') {
($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{$metric_label}, network => 1);
$extra_unit = '/s';
} else {
($value, $unit) = ($self->{result_values}->{$metric_label}, $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{unit});
}
my $msg = sprintf("%s: %.2f %s", $self->{instance_mode}->{metrics_mapping}->{ $self->{result_values}->{metric} }->{output}, $value, $unit . $extra_unit);
return $msg;
}
@ -112,16 +119,16 @@ sub set_counters {
$self->{maps_counters_type} = [
{ name => 'metrics', type => 3, cb_prefix_output => 'prefix_metric_output', cb_long_output => 'long_output',
message_multiple => defined($data->{extra_params}->{message_mutiple}) ? $data->{extra_params}->{message_mutiple} : 'All metrics are ok',
message_multiple => defined($data->{extra_params}->{message_multiple}) ? $data->{extra_params}->{message_multiple} : 'All metrics are ok',
indent_long_output => ' ',
group => [
{ name => 'statistics', display_long => 1, cb_prefix_output => 'prefix_statistics_output',
message_multiple => 'All metrics are ok', type => 1, skipped_code => { -10 => 1 } },
message_multiple => 'All metrics are ok', type => 1, skipped_code => { -10 => 1 } }
]
}
];
foreach my $metric (keys %{$self->{metrics_mapping}}) {
foreach my $metric (sort keys %{$self->{metrics_mapping}}) {
my $entry = {
label => $self->{metrics_mapping}->{$metric}->{label},
set => {

View File

@ -789,6 +789,56 @@ sub elasticache_describe_cache_clusters {
return $results;
}
sub directconnect_describe_connections {
my ($self, %options) = @_;
my $results = {};
eval {
my $ec = $self->{paws}->service('DirectConnect', region => $self->{option_results}->{region});
my $connections = $ec->DescribeConnections();
foreach (@{$connections->{Connections}}) {
$results->{ $_->{ConnectionId} } = { {
name => $_->{ConnectionName},
state => $_->{ConnectionState},
bandwidth => $_->{Bandwidth}
};
}
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "error: $@");
$self->{output}->option_exit();
}
return $results;
}
sub directconnect_describe_virtual_interfaces {
my ($self, %options) = @_;
my $results = {};
eval {
my $ec = $self->{paws}->service('DirectConnect', region => $self->{option_results}->{region});
my $vi = $ec->DescribeVirtualInterfaces();
foreach (@{$vi->{VirtualInterfaces}}) {
$results->{ $_->{VirtualInterfaceId} } = {
name => $_->{VirtualInterfaceName},
state => $_->{VirtualInterfaceState},
type => $_->{VirtualInterfaceType},
vlan => $_->{Vlan},
connectionId => $_->{ConnectionId}
};
}
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "error: $@");
$self->{output}->option_exit();
}
return $results;
}
1;
__END__

View File

@ -0,0 +1,249 @@
#
# Copyright 2023 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::aws::directconnect::mode::connections;
use base qw(cloud::aws::custom::mode);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub get_metrics_mapping {
my ($self, %options) = @_;
my $metrics_mapping = {
extra_params => {
message_multiple => 'All connections are ok'
},
metrics => {
ConnectionBpsEgress => {
output => 'outbound data',
label => 'connection-egress',
nlabel => {
absolute => 'connection.egress.bitspersecond',
},
unit => 'bps'
},
ConnectionBpsIngress => {
output => 'inbound data',
label => 'connection-ingress',
nlabel => {
absolute => 'connection.ingress.bitspersecond',
},
unit => 'bps'
},
ConnectionPpsEgress => {
output => 'outbound packets data',
label => 'connection-packets-egress',
nlabel => {
absolute => 'connection.egress.packets.persecond',
},
unit => '/s'
},
ConnectionPpsIngress => {
output => 'inbound packet data',
label => 'connection-packets-ingress',
nlabel => {
absolute => 'connection.ingress.packets.persecond',
},
unit => '/s'
},
ConnectionLightLevelTx => {
output => 'outbound light level',
label => 'connection-ligh-level-outbound',
nlabel => {
absolute => 'connection.outbound.light.level.dbm',
},
unit => 'dBm'
},
ConnectionLightLevelRx => {
output => 'inbound light level',
label => 'connection-ligh-level-inbound',
nlabel => {
absolute => 'connection.inbound.light.level.dbm',
},
unit => 'dBm'
}
}
};
return $metrics_mapping;
}
sub custom_status_output {
my ($self, %options) = @_;
return sprintf('state: %s [bandwidth: %s]', $self->{result_values}->{state}, $self->{result_values}->{bandwidth});
}
sub prefix_metric_output {
my ($self, %options) = @_;
return "connection '" . $options{instance_value}->{display} . "' ";
}
sub long_output {
my ($self, %options) = @_;
return "Checking connection '" . $options{instance_value}->{display} . "' ";
}
sub prefix_statistics_output {
my ($self, %options) = @_;
return "statistic '" . $options{instance_value}->{display} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->SUPER::set_counters(%options);
unshift @{$self->{maps_counters_type}->[0]->{group}}, {
name => 'status',
type => 0, skipped_code => { -10 => 1 }
};
$self->{maps_counters}->{status} = [
{ label => 'status', type => 2, set => {
key_values => [ { name => 'state' }, { name => 'bandwidth' }, { name => 'connectionName' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
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-connection-id:s' => { name => 'filter_connection_id' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $connections = $options{custom}->directconnect_describe_connections();
foreach my $connection_id (keys %$connections) {
next if (defined($self->{option_results}->{filter_connection_id}) && $self->{option_results}->{filter_connection_id} ne ''
&& $connection_id !~ /$self->{option_results}->{filter_connection_id}/);
$self->{metrics}->{$connection_id} = {
display => $connections->{$connection_id}->{name},
status => {
connectionName => $connections->{$connection_id}->{name},
bandwidth => $connections->{$connection_id}->{bandwidth},
state => $connections->{$connection_id}->{state}
},
statistics => {}
};
my $cw_metrics = $options{custom}->cloudwatch_get_metrics(
namespace => 'AWS/DX',
dimensions => [ { Name => 'ConnectionId', Value => $connection_id } ],
metrics => $self->{aws_metrics},
statistics => $self->{aws_statistics},
timeframe => $self->{aws_timeframe},
period => $self->{aws_period}
);
foreach my $metric (@{$self->{aws_metrics}}) {
foreach my $statistic (@{$self->{aws_statistics}}) {
next if (!defined($cw_metrics->{$metric}->{lc($statistic)}) &&
!defined($self->{option_results}->{zeroed}));
$self->{metrics}->{$connection_id}->{display} = $connections->{$connection_id}->{name};
$self->{metrics}->{$connection_id}->{statistics}->{lc($statistic)}->{display} = $statistic;
$self->{metrics}->{$connection_id}->{statistics}->{lc($statistic)}->{timeframe} = $self->{aws_timeframe};
$self->{metrics}->{$connection_id}->{statistics}->{lc($statistic)}->{$metric} =
defined($cw_metrics->{$metric}->{lc($statistic)}) ?
$cw_metrics->{$metric}->{lc($statistic)} : 0;
}
}
}
if (scalar(keys %{$self->{metrics}}) <= 0) {
$self->{output}->add_option_msg(short_msg => 'No connection found');
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check direct connect connections.
Example:
perl centreon_plugins.pl --plugin=cloud::aws::directconnect::plugin --custommode=paws --mode=connections --region='eu-west-1'
--filter-metric='ConnectionBpsEgress' --statistic='average' --critical-connection-egress='10Mb' --verbose
See 'https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html' for more informations.
Default statistic: 'average' / All satistics are valid.
=over 8
=item B<--filter-connection-id>
Filter connection id (can be a regexp).
=item B<--filter-metric>
Filter metrics (Can be: 'ConnectionBpsEgress', 'ConnectionBpsIngress',
'ConnectionPpsEgress', 'ConnectionPpsIngress', 'ConnectionLightLevelTx', 'ConnectionLightLevelRx')
(Can be a regexp).
=item B<--warning-status>
Set warning threshold for status.
Can used special variables like: %{state}, %{bandwidth}, %{connectionName}
=item B<--critical-status>
Set critical threshold for status.
Can used special variables like: %{state}, %{bandwidth}, %{connectionName}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be 'connection-egress', 'connection-ingress',
'connection-packets-egress', 'connection-packets-ingress',
'connection-ligh-level-outbound', 'connection-ligh-level-inbound.
=back
=cut

View File

@ -0,0 +1,104 @@
#
# Copyright 2023 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::aws::directconnect::mode::discovery;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use JSON::XS;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
'prettify' => { name => 'prettify' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub run {
my ($self, %options) = @_;
my @disco_data;
my $disco_stats;
$disco_stats->{start_time} = time();
my $connections = $options{custom}->directconnect_describe_connections();
foreach my $connection_id (keys %$connections) {
my %connection = (type => 'connection');
$connection{id} = $connection_id;
$connection{name} = $connections->{$connection_id}->{name};
$connection{state} = $connections->{$connection_id}->{state};
$connection{bandwidth} = $connections->{$connection_id}->{bandwidth};
push @disco_data, \%connection;
}
$disco_stats->{end_time} = time();
$disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time};
$disco_stats->{discovered_items} = @disco_data;
$disco_stats->{results} = \@disco_data;
my $encoded_data;
eval {
if (defined($self->{option_results}->{prettify})) {
$encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats);
} else {
$encoded_data = JSON::XS->new->utf8->encode($disco_stats);
}
};
if ($@) {
$encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}';
}
$self->{output}->output_add(short_msg => $encoded_data);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1);
$self->{output}->exit();
}
1;
__END__
=head1 MODE
AWS Direct Connect discovery.
=over 8
=item B<--prettify>
Prettify JSON output.
=back
=cut

View File

@ -0,0 +1,103 @@
#
# Copyright 2023 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::aws::directconnect::mode::listconnections;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
return $options{custom}->directconnect_describe_connections();
}
sub run {
my ($self, %options) = @_;
my $connections = $self->manage_selection(%options);
foreach my $connection_id (keys %$connections) {
$self->{output}->output_add(
long_msg => sprintf(
'[id: %s][name: %s][state: %s]',
$connection_id,
$connections->{$connection_id}->{name},
$connections->{$connection_id}->{state}
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List connections:'
);
$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', 'name', 'state']);
}
sub disco_show {
my ($self, %options) = @_;
my $connections = $self->manage_selection(%options);
foreach my $connection_id (keys %$connections) {
$self->{output}->add_disco_entry(
id => $connection_id,
name => $connections->{$connection_id}->{name},
state => $connections->{$connection_id}->{state}
);
}
}
1;
__END__
=head1 MODE
List direct connections.
=over 8
=back
=cut

View File

@ -0,0 +1,114 @@
#
# Copyright 2023 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::aws::directconnect::mode::listvirtualinterfaces;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $connections = $options{custom}->directconnect_describe_connections();
my $interfaces = $options{custom}->directconnect_describe_virtual_interfaces();
my $results = [];
foreach my $vid (keys %$interfaces) {
push @$results, {
connectionId => $interfaces->{$vid}->{connectionId},
connectionName => $connections->{ $interfaces->{$vid}->{connectionId} }->{name},
virtualInterfaceId => $vid,
virtualInterfaceName => $interfaces->{$vid}->{name},
virtualInterfaceState => $interfaces->{$vid}->{state}
};
}
return $results;
}
sub run {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->output_add(
long_msg => sprintf(
'[connectionId: %s][connectionName: %s][virtualInterfaceId: %s][virtualInterfaceName: %s][virtualInterfaceState: %s]',
$_->{connectionId},
$_->{connectionName},
$_->{virtualInterfaceId},
$_->{virtualInterfaceName},
$_->{virtualInterfaceState}
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List virtual interfaces:'
);
$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 => ['virtualInterfaceId', 'virtualInterfaceName', 'connectionName', 'connectionId', 'virtualInterfaceState']);
}
sub disco_show {
my ($self, %options) = @_;
my $results = $self->manage_selection(%options);
foreach (@$results) {
$self->{output}->add_disco_entry(%$_);
}
}
1;
__END__
=head1 MODE
List virtual interfaces.
=over 8
=back
=cut

View File

@ -0,0 +1,245 @@
#
# Copyright 2023 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::aws::directconnect::mode::virtualinterfaces;
use base qw(cloud::aws::custom::mode);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub get_metrics_mapping {
my ($self, %options) = @_;
my $metrics_mapping = {
extra_params => {
message_multiple => 'All virtual interfaces are ok'
},
metrics => {
VirtualInterfaceBpsEgress => {
output => 'outbound data',
label => 'virtual-interface-egress',
nlabel => {
absolute => 'virtual_interface.egress.bitspersecond',
},
unit => 'bps'
},
VirtualInterfaceBpsIngress => {
output => 'inbound data',
label => 'virtual-interface-ingress',
nlabel => {
absolute => 'virtual_interface.ingress.bitspersecond',
},
unit => 'bps'
},
VirtualInterfacePpsEgress => {
output => 'outbound packets data',
label => 'virtual-interface-packets-egress',
nlabel => {
absolute => 'virtual_interface.egress.packets.persecond',
},
unit => '/s'
},
VirtualInterfacePpsIngress => {
output => 'inbound packet data',
label => 'virtual-interface-packets-ingress',
nlabel => {
absolute => 'virtual_interface.ingress.packets.persecond',
},
unit => '/s'
}
}
};
return $metrics_mapping;
}
sub custom_status_output {
my ($self, %options) = @_;
return sprintf('state: %s [vlan: %s, type: %s]', $self->{result_values}->{state}, $self->{result_values}->{vlan}, $self->{result_values}->{type});
}
sub prefix_metric_output {
my ($self, %options) = @_;
return "connection '" . $options{instance_value}->{connectionName} . "' virtual interface '" . $options{instance_value}->{virtualInterfaceName} . "' ";
}
sub long_output {
my ($self, %options) = @_;
return "Checking connection '" . $options{instance_value}->{connectionName} . "' virtual interface '" . $options{instance_value}->{virtualInterfaceName} . "'";
}
sub prefix_statistics_output {
my ($self, %options) = @_;
return "statistic '" . $options{instance_value}->{display} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->SUPER::set_counters(%options);
unshift @{$self->{maps_counters_type}->[0]->{group}}, {
name => 'status',
type => 0, skipped_code => { -10 => 1 }
};
$self->{maps_counters}->{status} = [
{ label => 'status', type => 2, set => {
key_values => [ { name => 'state' }, { name => 'vlan' }, { name => 'type' }, { name => 'connectionName' }, { name => 'virtualInterfaceName' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
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-connection-id:s' => { name => 'filter_connection_id' },
'filter-virtual-interface-id:s' => { name => 'filter_virtual_interface_id' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $connections = $options{custom}->directconnect_describe_connections();
my $interfaces = $options{custom}->directconnect_describe_virtual_interfaces();
foreach my $vid (keys %$interfaces) {
next if (defined($self->{option_results}->{filter_virtual_interface_id}) && $self->{option_results}->{filter_virtual_interface_id} ne ''
&& $vid !~ /$self->{option_results}->{filter_virtual_interface_id}/);
next if (defined($self->{option_results}->{filter_connection_id}) && $self->{option_results}->{filter_connection_id} ne ''
&& $interfaces->{$vid}->{connectionId} !~ /$self->{option_results}->{filter_connection_id}/);
my $key = $connections->{ $interfaces->{$vid}->{connectionId} }->{name} . $self->{output}->get_instance_perfdata_separator() . $interfaces->{$vid}->{name};
$self->{metrics}->{$key} = {
connectionName => $connections->{ $interfaces->{$vid}->{connectionId} }->{name},
virtualInterfaceName => $interfaces->{$vid}->{name},
status => {
connectionName => $connections->{ $interfaces->{$vid}->{connectionId} }->{name},
virtualInterfaceName => $interfaces->{$vid}->{name},
type => $interfaces->{$vid}->{type},
vlan => $interfaces->{$vid}->{vlan},
state => $interfaces->{$vid}->{state}
},
statistics => {}
};
my $cw_metrics = $options{custom}->cloudwatch_get_metrics(
namespace => 'AWS/DX',
dimensions => [ { Name => 'ConnectionId', Value => $interfaces->{$vid}->{connectionId} }, { Name => 'VirtualInterfaceId', Value => $vid } ],
metrics => $self->{aws_metrics},
statistics => $self->{aws_statistics},
timeframe => $self->{aws_timeframe},
period => $self->{aws_period}
);
foreach my $metric (@{$self->{aws_metrics}}) {
foreach my $statistic (@{$self->{aws_statistics}}) {
next if (!defined($cw_metrics->{$metric}->{lc($statistic)}) &&
!defined($self->{option_results}->{zeroed}));
$self->{metrics}->{$key}->{display} = $interfaces->{$vid}->{name};
$self->{metrics}->{$key}->{statistics}->{lc($statistic)}->{display} = $statistic;
$self->{metrics}->{$key}->{statistics}->{lc($statistic)}->{timeframe} = $self->{aws_timeframe};
$self->{metrics}->{$key}->{statistics}->{lc($statistic)}->{$metric} =
defined($cw_metrics->{$metric}->{lc($statistic)}) ?
$cw_metrics->{$metric}->{lc($statistic)} : 0;
}
}
}
if (scalar(keys %{$self->{metrics}}) <= 0) {
$self->{output}->add_option_msg(short_msg => 'No virtual interface found');
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check direct connect virtual interfaces.
Example:
perl centreon_plugins.pl --plugin=cloud::aws::directconnect::plugin --custommode=paws --mode=virtual-interfaces --region='eu-west-1'
--filter-metric='VirtualInterfaceBpsEgress' --statistic='average' --critical-virtual-interface-egress='10Mb' --verbose
See 'https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html' for more informations.
Default statistic: 'average' / All satistics are valid.
=over 8
=item B<--filter-connection-id>
Filter connection id (can be a regexp).
=item B<--filter-virtual-interface-id>
Filter virtual interface id (can be a regexp).
=item B<--filter-metric>
Filter metrics (Can be: 'VirtualInterfaceBpsEgress', 'VirtualInterfaceBpsIngress',
'VirtualInterfacePpsEgress', 'VirtualInterfacePpsIngress')
(Can be a regexp).
=item B<--warning-status>
Set warning threshold for status.
Can used special variables like: %{state}, %{vlan}, %{type}, %{virtualInterfaceId}
=item B<--critical-status>
Set critical threshold for status.
Can used special variables like: %{state}, %{vlan}, %{type}, %{virtualInterfaceId}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be 'virtual-interface-egress', 'virtual-interface-ingress',
'virtual-interface-packets-egress', 'virtual-interface-packets-ingress'.
=back
=cut

View File

@ -0,0 +1,53 @@
#
# Copyright 2023 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::aws::directconnect::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->{modes} = {
'connections' => 'cloud::aws::directconnect::mode::connections',
'discovery' => 'cloud::aws::directconnect::mode::discovery',
'list-connections' => 'cloud::aws::directconnect::mode::listconnections',
'list-virtual-interfaces' => 'cloud::aws::directconnect::mode::listvirtualinterfaces',
'virtual-interfaces' => 'cloud::aws::directconnect::mode::virtualinterfaces'
};
$self->{custom_modes}->{paws} = 'cloud::aws::custom::paws';
$self->{custom_modes}->{awscli} = 'cloud::aws::custom::awscli';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Amazon Direct Connect.
=cut