diff --git a/cloud/aws/custom/awscli.pm b/cloud/aws/custom/awscli.pm new file mode 100644 index 000000000..2dc8e4319 --- /dev/null +++ b/cloud/aws/custom/awscli.pm @@ -0,0 +1,155 @@ +# +# Copyright 2015 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::custom::awscli; + +use strict; +use warnings; +use JSON; +use Data::Dumper; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + # $options{noptions} = integer + + 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 => + { + "region:s" => { name => 'region' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'AWSCLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + # options{default} + + # Manage default value + 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) = @_; + return 0; +} + +sub execReq { + my ($self, $options) = @_; + my $jsoncontent; + + if (!defined($options->{output})) { + $options->{output} = 'json'; + } + + my $json = JSON->new; + my $json_encoded = "aws ".$options->{command}." ".$options->{subcommand}; + if ( defined($self->{option_results}->{region})) { + $json_encoded = $json_encoded . " --region '" . $self->{option_results}->{region} . "'"; + } + if ( defined($options->{json})) { + $json_encoded = $json_encoded . " --cli-input-json '" . $json->encode($options->{json}) . "'"; + } + + if ($options->{output} eq 'text') { + my @return = `$json_encoded`; + chomp(@return); + $jsoncontent = $json->encode([@return]); + } + else { + $jsoncontent = `$json_encoded`; + } + if ($? > 0) { + $self->{output}->add_option_msg(short_msg => "Cannot run aws"); + $self->{output}->option_exit(); + } + eval { + $self->{command_return} = $json->decode($jsoncontent); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json answer"); + $self->{output}->option_exit(); + } + return $self->{command_return}; +} + +1; + +__END__ + +=head1 NAME + +AWS CLI API + +=head1 SYNOPSIS + +AWS cli API custom mode + +=over 8 + +=item B<--region> + +(optional) The region to use (should be configured directly in aws). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/cloud/aws/mode/cloudwatch.pm b/cloud/aws/mode/cloudwatch.pm new file mode 100644 index 000000000..43c5fef6e --- /dev/null +++ b/cloud/aws/mode/cloudwatch.pm @@ -0,0 +1,309 @@ +# +# Copyright 2015 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::mode::cloudwatch; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; +use Data::Dumper; +use POSIX; +use JSON; +use Module::Load; + +my $CloudwatchMetrics = { + 'cpu' => "cloud::aws::mode::metrics::ec2instancecpu", + 'traffic' => "cloud::aws::mode::metrics::ec2instancenetwork", + 'cpucreditusage' => "cloud::aws::mode::metrics::ec2instancecpucreditusage", + 'cpucreditbalance' => "cloud::aws::mode::metrics::ec2instancecpucreditbalance", + 'bucketsize' => "cloud::aws::mode::metrics::s3bucketsize", + 'rdscpu' => "cloud::aws::mode::metrics::rdsinstancecpu", +}; + +my $StatisticsType = "Average,Minimum,Maximum,Sum,SampleCount"; +my $def_endtime = time(); + +my $apiRequest = { + 'command' => 'cloudwatch', + 'subcommand' => 'get-metric-statistics', +}; + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + + $options{options}->add_options( + arguments => { + "metric:s" => { name => 'metric' }, + "period:s" => { name => 'period', default => 300 }, + "starttime:s" => { name => 'starttime' }, + "endtime:s" => { name => 'endtime' }, + "statistics:s" => { name => 'statistics', default => 'Average' }, + "exclude-statistics:s" => { name => 'exclude-statistics' }, + "object:s" => { name => 'object' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + } + ); + $self->{result} = {}; + + return $self; +} + +sub check_options { + my ( $self, %options ) = @_; + $self->SUPER::init(%options); + + $self->{option_results}->{def_endtime} = $def_endtime; + + if ( ( $self->{perfdata}->threshold_validate( label => 'warning' ,value => $self->{option_results}->{warning} ) ) == 0 ) + { + $self->{output} + ->add_option_msg( short_msg => "Wrong warning threshold '" + . $self->{option_results}->{warning} + . "'." ); + $self->{output}->option_exit(); + } + if ( ( $self->{perfdata}->threshold_validate( label => 'critical' ,value => $self->{option_results}->{critical} ) ) == 0 ) + { + $self->{output} + ->add_option_msg( short_msg => "Wrong critical threshold '" + . $self->{option_results}->{critical} + . "'." ); + $self->{output}->option_exit(); + } + + if ( !defined( $self->{option_results}->{metric} ) ) { + $self->{output}->add_option_msg( + severity => 'UNKNOWN', + short_msg => "Please give a metric to watch (cpu, disk, ...)." + ); + $self->{output}->option_exit(); + } + + if ( !defined( $self->{option_results}->{object} ) ) { + $self->{output}->add_option_msg( + severity => 'UNKNOWN', + short_msg => "Please give the object to request (instanceid, ...)." + ); + $self->{output}->option_exit(); + } + + if ( !defined( $self->{option_results}->{endtime} ) ) { + $self->{option_results}->{endtime} = + strftime( "%FT%H:%M:%S.000Z", + gmtime( $self->{option_results}->{def_endtime} ) ); + } + + if ( !defined( $self->{option_results}->{starttime} ) ) { + $self->{option_results}->{starttime} = + strftime( "%FT%H:%M:%S.000Z", + gmtime( $self->{option_results}->{def_endtime} - 600 ) ); + } + + # Getting some parameters + # statistics + if ( $self->{option_results}->{statistics} eq 'all' ) { + @{ $self->{option_results}->{statisticstab} } = split( /,/, $StatisticsType ); + } + else { + @{ $self->{option_results}->{statisticstab} } = split( /,/, $self->{option_results}->{statistics} ); + foreach my $curstate ( @{ $self->{option_results}->{statisticstab} } ) { + if ( !grep { /^$curstate$/ } split( /,/, $StatisticsType ) ) { + $self->{output}->add_option_msg( + severity => 'UNKNOWN', + short_msg => "The statistic $curstate doesn't exist." + ); + $self->{output}->option_exit(); + } + } + } + + # exclusions + if (defined($self->{option_results}->{'exclude-statistics'})){ + my @excludetab = split(/,/, $self->{option_results}->{'exclude-statistics'}); + my %array1 = map { $_ => 1 } @excludetab; + @{$self->{option_results}->{statisticstab}} = grep { not $array1{$_} } @{$self->{option_results}->{statisticstab}}; + } + + # Force Average statistic + if ( ! grep $_ eq 'Average', @{$self->{option_results}->{statisticstab}} ) { + my $statistics = join(',',@{ $self->{option_results}->{statisticstab} }); + if ( ! $statistics eq '' ) { + $statistics = $statistics . ',Average'; + } + else { + $statistics = 'Average'; + } + @{ $self->{option_results}->{statisticstab} } = split( /,/, $statistics ); + } +} + +sub manage_selection { + my ( $self, $metric ) = @_; + my @result; + + my @Dimensions = ( + { + 'Value' => $self->{option_results}->{object}, + 'Name' => $metric->{ObjectName} + } + ); + + if ( defined( $metric->{ExtraDimensions} ) ) { + push @Dimensions, $metric->{ExtraDimensions}; + } + + $apiRequest->{json} = { + 'StartTime' => $self->{option_results}->{starttime}, + 'EndTime' => $self->{option_results}->{endtime}, + 'Period' => $self->{option_results}->{period}, + 'MetricName' => $metric->{MetricName}, + 'Unit' => $metric->{Unit}, + 'Statistics' => $self->{option_results}->{statisticstab}, + 'Dimensions' => [@Dimensions], + 'Namespace' => $metric->{NameSpace} + }; +} + +sub run { + my ( $self, %options ) = @_; + + my ( $msg, $exit_code, $awsapi ); + + if ( defined( $CloudwatchMetrics->{ $self->{option_results}->{metric} } ) ) + { + load $CloudwatchMetrics->{ $self->{option_results}->{metric} },qw/cloudwatchCheck/; + cloudwatchCheck($self); + } + else { + $self->{output} + ->add_option_msg( short_msg => "Wrong option. Cannot find metric '" + . $self->{option_results}->{metric} + . "'." ); + $self->{output}->option_exit(); + } + + foreach my $metric ( @{ $self->{metric} } ) { + $self->manage_selection($metric); + $awsapi = $options{custom}; + $self->{command_return} = $awsapi->execReq($apiRequest); + $self->{output}->perfdata_add( + label => sprintf( + $metric->{Labels}->{PerfData}, + unit => $metric->{Labels}->{Unit} + ), + value => sprintf( + $metric->{Labels}->{Value}, + $self->{command_return}->{Datapoints}[0]->{Average} + ), + warning => $self->{perfdata}->get_perfdata_for_output( label => 'warning' ), + critical => $self->{perfdata}->get_perfdata_for_output( label => 'critical' ), + #min => 0, + #max => 100 + ); + $exit_code = $self->{perfdata}->threshold_check( + value => $self->{command_return}->{Datapoints}[0]->{Average}, + threshold => [ + { label => 'critical', 'exit_litteral' => 'critical' }, + { label => 'warning', exit_litteral => 'warning' } + ] + ); + + $self->{output}->output_add( + long_msg => sprintf( + $metric->{Labels}->{LongOutput}, + $self->{command_return}->{Datapoints}[0]->{Average} + ) + ); + + $self->{output}->output_add( + severity => $exit_code, + short_msg => sprintf( + $metric->{Labels}->{ShortOutput}, + $self->{command_return}->{Datapoints}[0]->{Average} + ) + ); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Get cloudwatch metrics. +This doc is partly based on the official AWS CLI documentation. + +=over 8 + +=item B<--exclude-statistics> + +(optional) Statistics to exclude from the query. 'Average' can't be excluded. + +=item B<--metric> + +Metric to query. + +=item B<--period> + +(optional) The granularity, in seconds, of the returned datapoints. period must be at least 60 seconds and must be a multiple of 60. The default value is 300. + +=item B<--start-time> + +(optional) The time stamp to use for determining the first datapoint to return. The value specified is inclusive; results include datapoints with the time stamp specified. +exemple: 2014-04-09T23:18:00 + +=item B<--end-time> + +(optional) The time stamp to use for determining the last datapoint to return. The value specified is exclusive; results will include datapoints up to the time stamp specified. +exemple: 2014-04-09T23:18:00 + +=item B<--statistics> + +(optional) The metric statistics to return. For information about specific statistics returned by GetMetricStatistics, go to statistics in the Amazon CloudWatch Developer Guide. +Valid Values: Average | Sum | SampleCount | Maximum | Minimum +Average is the default and always included. +'all' for all statistics values. + +=item B<--object> + +Name of the object to request (InstanceId for an EC2 instance, for exemple). + +=item B<--warning> + +(optional) Threshold warning. + +=item B<--critical> + +(optional) Threshold critical. + +=back + +=cut diff --git a/cloud/aws/mode/instancestate.pm b/cloud/aws/mode/instancestate.pm new file mode 100644 index 000000000..b7304a607 --- /dev/null +++ b/cloud/aws/mode/instancestate.pm @@ -0,0 +1,209 @@ +# +# Copyright 2015 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::mode::instancestate; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; +use Data::Dumper; +use JSON; + +my %EC2_instance_states = ( + 'pending' => 'WARNING', + 'running' => 'OK', + 'shutting-down' => 'CRITICAL', + 'terminated' => 'CRITICAL', + 'stopping' => 'CRITICAL', + 'stopped' => 'CRITICAL' +); + +my $apiRequest = { + 'command' => 'ec2', + 'subcommand' => 'describe-instance-status', +}; + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + + $options{options}->add_options( + arguments => { + "state:s" => { name => 'state', default => 'all' }, + "no-includeallinstances" => { name => 'includeallinstances' }, + "exclude:s" => { name => 'exclude' }, + "instanceid:s" => { name => 'instanceid' } + } + ); + $self->{result} = {}; + return $self; +} + +sub check_options { + my ( $self, %options ) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ( $self, %options ) = @_; + + my ( @result, $awsapi ); + + # Getting some parameters + # includeallinstances + if ( defined( $self->{option_results}->{includeallinstances} ) ) { + $self->{option_results}->{includeallinstances} = JSON::false; + } + else { + $self->{option_results}->{includeallinstances} = JSON::true; + } + + # states + if ( $self->{option_results}->{state} eq 'all' ) { + @{ $self->{option_results}->{statetab} } = keys(%EC2_instance_states); + } + else { + @{ $self->{option_results}->{statetab} } = split( /,/, $self->{option_results}->{state} ); + foreach my $curstate ( @{ $self->{option_results}->{statetab} } ) { + if ( !grep { /^$curstate$/ } keys(%EC2_instance_states) ) { + $self->{output}->add_option_msg( severity => 'UNKNOWN', short_msg => "The state doesn't exist." ); + $self->{output}->option_exit(); + } + } + } + + # exclusions + if ( defined( $self->{option_results}->{exclude} ) ) { + my @excludetab = split( /,/, $self->{option_results}->{exclude} ); + my %array1 = map { $_ => 1 } @excludetab; + @{ $self->{option_results}->{statetab} } = grep { not $array1{$_} } @{ $self->{option_results}->{statetab} }; + } + my $states = join(',',@{ $self->{option_results}->{statetab} }); + + # Getting data from AWS + # Building JSON + $apiRequest->{json} = { + 'DryRun' => JSON::false, + 'IncludeAllInstances' => $self->{option_results}->{includeallinstances}, + 'Filters' => [ + { + 'Name' => 'instance-state-name', + 'Values' => $self->{option_results}->{statetab}, + }], + }; + # InstanceIds + if ( defined( $self->{option_results}->{instanceid} ) ) { + my @InstanceIds = split(/,/,$self->{option_results}->{instanceid}); + @{$apiRequest->{json}{'InstanceIds'}} = @InstanceIds; + } + + # Requesting API + $awsapi = $options{custom}; + $self->{command_return} = $awsapi->execReq($apiRequest); + + # Compute data + $self->{option_results}->{instancecount}->{'total'} = '0'; + foreach my $curstate ( @{ $self->{option_results}->{statetab} } ) { + $self->{option_results}->{instancecount}->{$curstate} = '0'; + } + foreach my $l ( @{ $self->{command_return}->{InstanceStatuses} } ) { + $self->{result}->{instance}->{ $l->{InstanceId} } = $l->{InstanceState}->{Name}; + + # long output for each instance + $self->{output}->output_add( long_msg => "'" . $l->{InstanceId} . "' [state = " . $l->{InstanceState}->{Name} . ']' ); + + foreach my $curstate ( @{ $self->{option_results}->{statetab} } ) { + if ( $l->{InstanceState}->{Name} eq $curstate ) { + $self->{option_results}->{instancecount}->{$curstate}++; + } + } + $self->{option_results}->{instancecount}->{'total'}++; + } +} + +sub run { + my ( $self, %options ) = @_; + + my ( $msg, $exit_code ); + my $old_status = 'OK'; + + $self->manage_selection(%options); + + # Send formated data to Centreon + # Perf data + $self->{output}->perfdata_add( + label => 'total', + value => $self->{option_results}->{instancecount}->{'total'}, + ); + + foreach my $curstate ( @{ $self->{option_results}->{statetab} } ) { + $self->{output}->perfdata_add( + label => $curstate, + value => $self->{option_results}->{instancecount}->{$curstate}, + ); + + # Most critical state + if ( $self->{option_results}->{instancecount}->{$curstate} != '0' ) { + $exit_code = $EC2_instance_states{$curstate}; + $exit_code = $self->{output}->get_most_critical( status => [ $exit_code, $old_status ] ); + $old_status = $exit_code; + } + } + + # Output message + $self->{output}->output_add( + severity => $exit_code, + short_msg => sprintf( "Total instances: %s", $self->{option_results}->{instancecount}->{'total'} ) + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Get the state of your EC2 instances (running, stopped, ...) + +=over 8 + +=item B<--state> + +(optional) Specific state to query. + +=item B<--no-includeallinstances> + +(optional) Includes the health status for running instances only. + +=item B<--exclude> + +(optional) State to exclude from the query. + +=back + +=cut diff --git a/cloud/aws/mode/list.pm b/cloud/aws/mode/list.pm new file mode 100644 index 000000000..a1eb79835 --- /dev/null +++ b/cloud/aws/mode/list.pm @@ -0,0 +1,254 @@ +# +# Copyright 2015 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::mode::list; + +use base qw(centreon::plugins::mode); +use strict; +use warnings; +use centreon::plugins::misc; +use Data::Dumper; +use JSON; + +my $AWSServices = 'EC2,S3,RDS'; +my @Disco_service_tab = ('EC2', 'RDS'); +my @EC2_instance_states = [ 'running', 'stopped' ]; + +my $awsapi; + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + + $options{options}->add_options( + arguments => { + "service:s" => { name => 'service', default => $AWSServices }, + "exclude:s" => { name => 'exclude' }, + } + ); + $self->{result} = {}; + return $self; +} + +sub check_options { + my ( $self, %options ) = @_; + $self->SUPER::init(%options); +} + +sub api_request { + my ( $self, %options ) = @_; + + @{ $self->{option_results}->{servicetab} } = + split( /,/, $self->{option_results}->{service} ); + foreach my $service ( @{ $self->{option_results}->{servicetab} } ) { + $self->{result}->{count}->{$service} = '0'; + if ( $service eq 'EC2' ) { + $self->EC2(%options); + } + elsif ( $service eq 'S3' ) { + $self->S3(%options); + } + elsif ( $service eq 'RDS' ) { + $self->RDS(%options); + } + else { + $self->{output}->add_option_msg( + short_msg => "Service $service doesn't exists" ); + $self->{output}->option_exit(); + } + } +} + +sub EC2 { + my ( $self, %options ) = @_; + + my $apiRequest = { + 'command' => 'ec2', + 'subcommand' => 'describe-instances', + }; + + # Building JSON + $apiRequest->{json} = { + 'DryRun' => JSON::false, + 'Filters' => [ + { + 'Name' => 'instance-state-name', + 'Values' => @EC2_instance_states, + } + ], + }; + + # Requesting API + $awsapi = $options{custom}; + $self->{command_return} = $awsapi->execReq($apiRequest); + + # Compute data + foreach my $instance ( @{ $self->{command_return}->{Reservations} } ) { + foreach my $tags ( @{ $instance->{Instances}[0]->{Tags} } ) { + if ( $tags->{Key} eq 'Name' ) { + $instance->{Instances}[0]->{Name} = $tags->{Value}; + } + } + $self->{result}->{'EC2'}->{ $instance->{Instances}[0]->{InstanceId} } = + { + 'State' => $instance->{Instances}[0]->{State}->{Name}, + 'Name' => $instance->{Instances}[0]->{Name} + }; + + $self->{result}->{count}->{'EC2'}++; + } +} + +sub S3 { + my ( $self, %options ) = @_; + my ( @buckets, @return ) = (); + + my $apiRequest = { + 'command' => 's3', + 'subcommand' => 'ls', + 'output' => 'text' + }; + + # Requesting API + $awsapi = $options{custom}; + $self->{command_return} = $awsapi->execReq($apiRequest); + + # Exec command + foreach my $line ( @{ $self->{command_return} } ) { + my ( $date, $time, $name ) = split( / /, $line ); + my $creationdate = $date . " " . $time; + push( @buckets, { Name => $name, CreationDate => $creationdate } ); + } + + # Compute data + foreach my $bucket (@buckets) { + $self->{result}->{'S3'}->{ $bucket->{Name} } = + { 'Creation date' => $bucket->{CreationDate} }; + $self->{result}->{count}->{'S3'}++; + } +} + +sub RDS { + my ( $self, %options ) = @_; + + my $apiRequest = { + 'command' => 'rds', + 'subcommand' => 'describe-db-instances', + }; + + # Requesting API + $awsapi = $options{custom}; + $self->{command_return} = $awsapi->execReq($apiRequest); + + # Compute data + foreach my $dbinstance ( @{ $self->{command_return}->{DBInstances} } ) { + $self->{result}->{'RDS'}->{ $dbinstance->{DBInstanceIdentifier} } = { + 'State' => $dbinstance->{DBInstanceStatus}, + 'Name' => $dbinstance->{DBInstanceIdentifier} + }; + $self->{result}->{count}->{'RDS'}++; + } +} + +sub disco_format { + my ( $self, %options ) = @_; + + my $names = [ 'name', 'id', 'state', 'service' ]; + $self->{output}->add_disco_format( elements => $names ); +} + +sub disco_show { + my ( $self, %options ) = @_; + + $self->api_request(%options); + + foreach my $service ( @Disco_service_tab ) { + foreach my $device ( keys %{ $self->{result}->{$service} } ) { + $self->{output}->add_disco_entry( + name => $self->{result}->{$service}->{$device}->{Name}, + id => $device, + state => $self->{result}->{$service}->{$device}->{State}, + service => $service, + ); + } + } +} + +sub run { + my ( $self, %options ) = @_; + + $self->api_request(%options); + + # Send formated data to Centreon + foreach my $service ( @{ $self->{option_results}->{servicetab} } ) { + $self->{output} + ->output_add( long_msg => sprintf( "AWS service: %s", $service ) ); + foreach my $device ( keys %{ $self->{result}->{$service} } ) { + my $output = $device . " ["; + foreach my $value ( + sort( keys %{ $self->{result}->{$service}->{$device} } ) ) + { + $output = + $output + . $value . " = " + . $self->{result}->{$service}->{$device}->{$value} . ", "; + } + $output =~ s/, $//; + $output = $output . "]"; + $self->{output}->output_add( long_msg => $output ); + } + $self->{output}->output_add( + short_msg => sprintf( "%s: %s", + $service, $self->{result}->{count}->{$service} ) + ); + } + + $self->{output}->display( + nolabel => 1, + force_ignore_perfdata => 1, + force_long_output => 1 + ); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +List your EC2, RDS instance and S3 buckets + +=over 8 + +=item B<--service> + +(optional) List one particular service. + +=item B<--exclude> + +(optional) Service to exclude from the scan. + +=back + +=cut diff --git a/cloud/aws/mode/metrics/ec2instancecpu.pm b/cloud/aws/mode/metrics/ec2instancecpu.pm new file mode 100644 index 000000000..221427073 --- /dev/null +++ b/cloud/aws/mode/metrics/ec2instancecpu.pm @@ -0,0 +1,51 @@ +# +# Copyright 2015 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::mode::metrics::ec2instancecpu; + +use strict; +use warnings; +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(&cloudwatchCheck); + +my @Param; + +$Param[0] = { + 'NameSpace' => 'AWS/EC2', + 'MetricName' => 'CPUUtilization', + 'ObjectName' => 'InstanceId', + 'Unit' => 'Percent', + 'Labels' => { + 'ShortOutput' => "CPU Usage is %.2f%%", + 'LongOutput' => "CPU Usage is %.2f%%", + 'PerfData' => 'cpu', + 'Unit' => '%', + 'Value' => "%.2f", + } +}; + +sub cloudwatchCheck { + my ($self) = @_; + + @{ $self->{metric} } = @Param; +} + +1; diff --git a/cloud/aws/mode/metrics/ec2instancecpucreditbalance.pm b/cloud/aws/mode/metrics/ec2instancecpucreditbalance.pm new file mode 100644 index 000000000..4158f2dc8 --- /dev/null +++ b/cloud/aws/mode/metrics/ec2instancecpucreditbalance.pm @@ -0,0 +1,51 @@ +# +# Copyright 2015 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::mode::metrics::ec2instancecpucreditbalance; + +use strict; +use warnings; +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(&cloudwatchCheck); + +my @Param; + +$Param[0] = { + 'NameSpace' => 'AWS/EC2', + 'MetricName' => 'CPUCreditBalance', + 'ObjectName' => 'InstanceId', + 'Unit' => 'Count', + 'Labels' => { + 'ShortOutput' => "CPUCreditBalance is %.2f%%", + 'LongOutput' => "CPUCreditBalance is %.2f%%", + 'PerfData' => 'CPUCreditBalance', + 'Unit' => 'Count', + 'Value' => "%.2f", + } +}; + +sub cloudwatchCheck { + my ($self) = @_; + + @{ $self->{metric} } = @Param; +} + +1; diff --git a/cloud/aws/mode/metrics/ec2instancecpucreditusage.pm b/cloud/aws/mode/metrics/ec2instancecpucreditusage.pm new file mode 100644 index 000000000..7b41e2696 --- /dev/null +++ b/cloud/aws/mode/metrics/ec2instancecpucreditusage.pm @@ -0,0 +1,51 @@ +# +# Copyright 2015 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::mode::metrics::ec2instancecpucreditusage; + +use strict; +use warnings; +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(&cloudwatchCheck); + +my @Param; + +$Param[0] = { + 'NameSpace' => 'AWS/EC2', + 'MetricName' => 'CPUCreditUsage', + 'ObjectName' => 'InstanceId', + 'Unit' => 'Count', + 'Labels' => { + 'ShortOutput' => "CPUCreditUsage is %.2f%%", + 'LongOutput' => "CPUCreditUsage is %.2f%%", + 'PerfData' => 'CPUCreditUsage', + 'Unit' => 'Count', + 'Value' => "%.2f", + } +}; + +sub cloudwatchCheck { + my ($self) = @_; + + @{ $self->{metric} } = @Param; +} + +1; diff --git a/cloud/aws/mode/metrics/ec2instancenetwork.pm b/cloud/aws/mode/metrics/ec2instancenetwork.pm new file mode 100644 index 000000000..3eea9ef7f --- /dev/null +++ b/cloud/aws/mode/metrics/ec2instancenetwork.pm @@ -0,0 +1,65 @@ +# +# Copyright 2015 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::mode::metrics::ec2instancenetwork; + +use strict; +use warnings; +use Data::Dumper; +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(&cloudwatchCheck); + +my @Param; + +$Param[0] = { + 'NameSpace' => 'AWS/EC2', + 'MetricName' => 'NetworkIn', + 'ObjectName' => 'InstanceId', + 'Unit' => 'Bytes', + 'Labels' => { + 'ShortOutput' => "Traffic In %s Bytes", + 'LongOutput' => "Traffic In %s Bytes", + 'PerfData' => 'traffic_in', + 'Unit' => 'B', + 'Value' => "%.2f", + } +}; + +$Param[1] = { + 'NameSpace' => 'AWS/EC2', + 'MetricName' => 'NetworkOut', + 'ObjectName' => 'InstanceId', + 'Labels' => { + 'ShortOutput' => "Traffic Out %s Bytes", + 'LongOutput' => "Traffic Out %s Bytes", + 'PerfData' => 'traffic_out', + 'Unit' => 'B', + 'Value' => "%.2f", + } +}; + +sub cloudwatchCheck { + my ($self) = @_; + + @{ $self->{metric} } = @Param; +} + +1; diff --git a/cloud/aws/mode/metrics/rdsinstancecpu.pm b/cloud/aws/mode/metrics/rdsinstancecpu.pm new file mode 100644 index 000000000..48b8f88ec --- /dev/null +++ b/cloud/aws/mode/metrics/rdsinstancecpu.pm @@ -0,0 +1,53 @@ +# +# Copyright 2015 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::mode::metrics::rdsinstancecpu; + +use strict; +use warnings; +use POSIX; +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(&cloudwatchCheck); + +my @Param; + +$Param[0] = { + 'NameSpace' => 'AWS/RDS', + 'MetricName' => 'CPUUtilization', + 'ObjectName' => 'DBInstanceIdentifier', + 'Unit' => 'Percent', + 'Labels' => { + 'ShortOutput' => "CPU Usage is %.2f%%", + 'LongOutput' => "CPU Usage is %.2f%%", + 'PerfData' => 'cpu', + 'Unit' => '%', + 'Value' => "%.2f", + } +}; + +sub cloudwatchCheck { + my ($self) = @_; + + @{ $self->{metric} } = @Param; + $self->{option_results}->{starttime} = strftime( "%FT%H:%M:%S.000Z", gmtime( $self->{option_results}->{def_endtime} - 300 ) ); +} + +1; diff --git a/cloud/aws/mode/metrics/s3bucketsize.pm b/cloud/aws/mode/metrics/s3bucketsize.pm new file mode 100644 index 000000000..799ff2f41 --- /dev/null +++ b/cloud/aws/mode/metrics/s3bucketsize.pm @@ -0,0 +1,74 @@ +# +# Copyright 2015 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::mode::metrics::s3bucketsize; + +use strict; +use warnings; +use POSIX; +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(&cloudwatchCheck); + +my @Param; + +$Param[0] = { + 'NameSpace' => 'AWS/S3', + 'MetricName' => 'BucketSizeBytes', + 'ObjectName' => 'BucketName', + 'Unit' => 'Bytes', + 'ExtraDimensions' => { + 'Name' => 'StorageType', + 'Value'=> 'StandardStorage' + }, + 'Labels' => { + 'ShortOutput' => "Bucket size is %s Bytes", + 'LongOutput' => "Bucket size is %s Bytes", + 'PerfData' => 'size', + 'Unit' => 'Bytes', + 'Value' => "%s", + } +}; +$Param[1] = { + 'NameSpace' => 'AWS/S3', + 'MetricName' => 'NumberOfObjects', + 'ObjectName' => 'BucketName', + 'Unit' => 'Count', + 'ExtraDimensions' => { + 'Name' => 'StorageType', + 'Value'=> 'AllStorageTypes' + }, + 'Labels' => { + 'ShortOutput' => "Number of objects is %s", + 'LongOutput' => "Number of objects is %s", + 'PerfData' => 'number', + 'Unit' => '', + 'Value' => "%s", + } +}; + +sub cloudwatchCheck { + my ($self) = @_; + + @{ $self->{metric} } = @Param; + $self->{option_results}->{starttime} = strftime( "%FT%H:%M:%S.000Z", gmtime( $self->{option_results}->{def_endtime} - 86400 ) ); +} + +1; diff --git a/cloud/aws/plugin.pm b/cloud/aws/plugin.pm new file mode 100644 index 000000000..30eafebb6 --- /dev/null +++ b/cloud/aws/plugin.pm @@ -0,0 +1,66 @@ +# +# Copyright 2015 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::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} } = ( + 'instancestate' => 'cloud::aws::mode::instancestate', + 'list' => 'cloud::aws::mode::list', + 'cloudwatch' => 'cloud::aws::mode::cloudwatch', + ); + + $self->{custom_modes}{awscli} = 'cloud::aws::custom::awscli'; + return $self; +} + +sub init { + my ( $self, %options ) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Amazon AWS cloud. + +=over 8 + +For this plugin to work, you have to install and configure: +awscli (http://docs.aws.amazon.com/cli/latest/userguide/installing.html#install-bundle-other-os). +perl-json +perl-Module-Load + +=back + +=cut