From 1573b83d0ff163fe876db9f9d27cb7159c739361 Mon Sep 17 00:00:00 2001 From: Sims24 Date: Mon, 20 Apr 2020 15:36:37 +0200 Subject: [PATCH] add ec2 spot fleet instance ocunt ref #172 --- cloud/aws/custom/awscli.pm | 30 ++++++ cloud/aws/custom/paws.pm | 30 +++++- cloud/aws/ec2/mode/spotactiveinstances.pm | 122 ++++++++++++++++++++++ cloud/aws/ec2/plugin.pm | 21 ++-- 4 files changed, 190 insertions(+), 13 deletions(-) create mode 100644 cloud/aws/ec2/mode/spotactiveinstances.pm diff --git a/cloud/aws/custom/awscli.pm b/cloud/aws/custom/awscli.pm index ab62709fb..36510b5d2 100644 --- a/cloud/aws/custom/awscli.pm +++ b/cloud/aws/custom/awscli.pm @@ -369,6 +369,36 @@ sub ec2_get_instances_status { return $instance_results; } +sub ec2spot_get_active_instances_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "ec2 describe-spot-fleet-instances --no-dry-run --region $options{region} --output json"; + $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + $cmd_options .= " --spot-fleet-request-id " . $options{spot_fleet_request_id}; + + return $cmd_options; +} + +sub ec2spot_get_active_instances_status { + my ($self, %options) = @_; + + my $cmd_options = $self->ec2spot_get_active_instances_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + my $instance_results = {}; + foreach (@{$raw_results->{ActiveInstances}}) { + $instance_results->{$_->{InstanceId}} = { + health => $_->{InstanceHealth}, + type => $_->{InstanceType}, + request_id => $_->{SpotInstanceRequestId} + }; + } + + return $instance_results; +} + sub ec2_list_resources_set_cmd { my ($self, %options) = @_; diff --git a/cloud/aws/custom/paws.pm b/cloud/aws/custom/paws.pm index cc899ba34..a1cab9d9e 100644 --- a/cloud/aws/custom/paws.pm +++ b/cloud/aws/custom/paws.pm @@ -301,7 +301,31 @@ sub ec2_get_instances_status { foreach (@{$instances->{InstanceStatuses}}) { $instance_results->{$_->{InstanceId}} = { state => $_->{InstanceState}->{Name}, - status => => $_->{InstanceStatus}->{Status} }; + status => $_->{InstanceStatus}->{Status} }; + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $instance_results; +} + +sub ec2spot_get_active_instances { + my ($self, %options) = @_; + + my $instance_results = {}; + eval { + my $lwp_caller = new Paws::Net::LWPCaller(); + my $ec2 = Paws->service('EC2', caller => $lwp_caller, region => $options{region}); + my $instances = $ec2->DescribeSpotFleetInstances('SpotFleetRequestId' => $options{spot_fleet_request_id}, DryRun => 0, IncludeAllInstances => 1); + + foreach (@{$instances->{ActiveInstances}}) { + $instance_results->{$_->{InstanceId}} = { + health => $_->{InstanceHealth}, + type => $_->{InstanceType}, + request_id => $_->{SpotInstanceRequestId} }; } }; if ($@) { @@ -451,7 +475,7 @@ sub vpn_list_connections { my $connections_results = []; eval { my $lwp_caller = new Paws::Net::LWPCaller(); - my $rds = Paws->service('EC2', caller => $lwp_caller, region => $options{region}); + my $vpn = Paws->service('EC2', caller => $lwp_caller, region => $options{region}); my $list_vpn = $vpn->DescribeVpnConnections(); foreach my $connection (@{$list_vpn->{VpnConnections}}) { my @name_tags; @@ -531,4 +555,4 @@ Proxy URL if any B. -=cut \ No newline at end of file +=cut diff --git a/cloud/aws/ec2/mode/spotactiveinstances.pm b/cloud/aws/ec2/mode/spotactiveinstances.pm new file mode 100644 index 000000000..1b544efe8 --- /dev/null +++ b/cloud/aws/ec2/mode/spotactiveinstances.pm @@ -0,0 +1,122 @@ +# +# Copyright 2020 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::ec2::mode::spotactiveinstances; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'active', nlabel => 'ec2.spot.instances.active.count', set => { + key_values => [ { name => 'active' } ], + output_template => 'Active instances : %s', + perfdatas => [ + { label => 'active', value => 'active_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'healthy', nlabel => 'ec2.spot.instances.unhealthy.count', set => { + key_values => [ { name => 'healthy' } ], + output_template => 'Healthy instances : %s', + perfdatas => [ + { label => 'healthy', value => 'healthy_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'unhealthy', nlabel => 'ec2.spot.instances.unhealthy.count', set => { + key_values => [ { name => 'unhealthy' } ], + output_template => 'Unhealty instances : %s', + perfdatas => [ + { label => 'unhealthy', value => 'unhealthy_absolute', template => '%s', + min => 0 }, + ], + } + }, + ] +} + +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 => { + 'region:s' => { name => 'region' }, + 'spot-fleet-request-id:s' => { name => 'spot_fleet_request_id' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{region}) || $self->{option_results}->{region} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --region option."); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{spot_fleet_request_id}) || $self->{option_results}->{spot_fleet_request_id} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --spot-fleet-request-id option."); + $self->{output}->option_exit(); + } + +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { active => 0, healthy => 0, unhealthy => 0 }; + $self->{instances} = $options{custom}->ec2spot_get_active_instances_status(region => $self->{option_results}->{region}, spot_fleet_request_id => $self->{option_results}->{spot_fleet_request_id}); + + foreach my $instance_id (keys %{$self->{instances}}) { + $self->{global}->{active}++; + $self->{global}->{lc($self->{instances}->{$instance_id}->{health})}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check EC2 Spot active instance for a specific fleet + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Warning and Critical thresholds. You can use 'active', 'healthy', 'unhealthy' + +=back + +=cut diff --git a/cloud/aws/ec2/plugin.pm b/cloud/aws/ec2/plugin.pm index e8eabedaa..a359235ba 100644 --- a/cloud/aws/ec2/plugin.pm +++ b/cloud/aws/ec2/plugin.pm @@ -31,16 +31,17 @@ sub new { $self->{version} = '0.1'; %{ $self->{modes} } = ( - 'asg-status' => 'cloud::aws::ec2::mode::asgstatus', - 'cpu' => 'cloud::aws::ec2::mode::cpu', - 'discovery' => 'cloud::aws::ec2::mode::discovery', - 'diskio' => 'cloud::aws::ec2::mode::diskio', - 'instances-status' => 'cloud::aws::ec2::mode::instancesstatus', - 'instances-types' => 'cloud::aws::ec2::mode::instancestypes', - 'list-asg' => 'cloud::aws::ec2::mode::listasg', - 'list-instances' => 'cloud::aws::ec2::mode::listinstances', - 'network' => 'cloud::aws::ec2::mode::network', - 'status' => 'cloud::aws::ec2::mode::status', + 'asg-status' => 'cloud::aws::ec2::mode::asgstatus', + 'cpu' => 'cloud::aws::ec2::mode::cpu', + 'discovery' => 'cloud::aws::ec2::mode::discovery', + 'diskio' => 'cloud::aws::ec2::mode::diskio', + 'instances-status' => 'cloud::aws::ec2::mode::instancesstatus', + 'instances-types' => 'cloud::aws::ec2::mode::instancestypes', + 'list-asg' => 'cloud::aws::ec2::mode::listasg', + 'list-instances' => 'cloud::aws::ec2::mode::listinstances', + 'network' => 'cloud::aws::ec2::mode::network', + 'status' => 'cloud::aws::ec2::mode::status', + 'spot-active-instances' => 'cloud::aws::ec2::mode::spotactiveinstances' ); $self->{custom_modes}{paws} = 'cloud::aws::custom::paws';