diff --git a/cloud/google/gcp/compute/computeengine/mode/discovery.pm b/cloud/google/gcp/compute/computeengine/mode/discovery.pm new file mode 100644 index 000000000..0be13a025 --- /dev/null +++ b/cloud/google/gcp/compute/computeengine/mode/discovery.pm @@ -0,0 +1,118 @@ +# +# 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::google::gcp::compute::computeengine::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 $instances = $options{custom}->gcp_list_compute_engine_instances(); + foreach my $instance (@$instances) { + my $item = {}; + $item->{id} = $instance->{id}; + $item->{name} = $instance->{name}; + $item->{description} = $instance->{description}; + $item->{status} = $instance->{status}; + $item->{cpu_platform} = $instance->{cpuPlatform}; + if ($instance->{machineType} =~ /machineTypes\/(.*?)$/) { + $item->{machine_type} = $1; + } + if ($instance->{zone} =~ /zones\/(.*?)$/) { + $item->{zone} = $1; + } + $item->{network_interfaces} = []; + foreach (@{$instance->{networkInterfaces}}) { + push @{$item->{network_interfaces}}, { name => $_->{name}, ip => $_->{networkIP} }; + } + $item->{tags} = []; + if (defined($instance->{tags}->{items})) { + push @{$item->{tags}}, @{$instance->{tags}->{items}}; + } + + push @$disco_data, $item; + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = scalar(@$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 + +Compute engine discovery. + +=over 8 + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/cloud/google/gcp/compute/computeengine/plugin.pm b/cloud/google/gcp/compute/computeengine/plugin.pm index ce2d21871..d7a4427df 100644 --- a/cloud/google/gcp/compute/computeengine/plugin.pm +++ b/cloud/google/gcp/compute/computeengine/plugin.pm @@ -31,9 +31,10 @@ sub new { $self->{version} = '0.1'; $self->{modes} = { - 'cpu' => 'cloud::google::gcp::compute::computeengine::mode::cpu', - 'diskio' => 'cloud::google::gcp::compute::computeengine::mode::diskio', - 'network' => 'cloud::google::gcp::compute::computeengine::mode::network' + 'cpu' => 'cloud::google::gcp::compute::computeengine::mode::cpu', + 'discovery' => 'cloud::google::gcp::compute::computeengine::mode::discovery', + 'diskio' => 'cloud::google::gcp::compute::computeengine::mode::diskio', + 'network' => 'cloud::google::gcp::compute::computeengine::mode::network' }; $self->{custom_modes}->{api} = 'cloud::google::gcp::custom::api'; diff --git a/cloud/google/gcp/custom/api.pm b/cloud/google/gcp/custom/api.pm index 248dc58df..143695caf 100644 --- a/cloud/google/gcp/custom/api.pm +++ b/cloud/google/gcp/custom/api.pm @@ -112,7 +112,7 @@ sub settings { sub get_access_token { my ($self, %options) = @_; - my $has_cache_file = $options{statefile}->read(statefile => 'gcp_api_' . md5_hex($self->{key_file})); + my $has_cache_file = $options{statefile}->read(statefile => 'gcp_api_' . md5_hex($self->{key_file} . ':' . $self->{authorization_endpoint})); my $expires_on = $options{statefile}->get(name => 'expires_on'); my $access_token = $options{statefile}->get(name => 'access_token'); @@ -376,6 +376,90 @@ sub gcp_get_metrics { return $results; } +sub request_api_paginate { + my ($self, %options) = @_; + + my $items = []; + my $get_param; + $get_param = $options{get_param} if (defined$options{get_param}); + while (1) { + my $response = $self->request_api( + method => 'GET', + full_url => $options{url}, + hostname => '', + get_param => $get_param + ); + last if (!defined($response->{items})); + push @$items, @{$response->{items}}; + + last if (!defined($response->{nextPageToken})); + $get_param = [@{$options{get_param}}, 'pageToken=' . $response->{nextPageToken}]; + } + + return $items; +} + +sub gcp_compute_engine_set_base_url { + my ($self, %options) = @_; + + my $project_id = $self->get_project_id(); + my $url = 'https://compute.googleapis.com/compute/v1/projects/' . $project_id; + return $url; +} + +sub gcp_list_compute_engine_zones { + my ($self, %options) = @_; + + my $url = $self->gcp_compute_engine_set_base_url(); + my $zones = $self->request_api_paginate( + url => $url . '/zones' + ); + return $zones; +} + +sub gcp_list_compute_engine_instances { + my ($self, %options) = @_; + + my $results = []; + my $url = $self->gcp_compute_engine_set_base_url(); + my $zones = $self->gcp_list_compute_engine_zones(); + foreach (@$zones) { + my $instances = $self->request_api_paginate( + url => $url . '/zones/' . $_->{name} . '/instances' + ); + push @$results, @$instances; + } + return $results; +} + +sub gcp_cloudsql_set_base_url { + my ($self, %options) = @_; + + my $project_id = $self->get_project_id(); + my $url = 'https://sqladmin.googleapis.com/sql/v1beta4/projects/' . $project_id; + return $url; +} + +sub gcp_list_cloudsql_instances { + my ($self, %options) = @_; + + my $url = $self->gcp_cloudsql_set_base_url(); + my $instances = $self->request_api_paginate( + url => $url . '/instances' + ); + return $instances; +} + +sub gcp_list_storage_buckets { + my ($self, %options) = @_; + + my $buckets = $self->request_api_paginate( + url => 'https://storage.googleapis.com/storage/v1/b', + get_param => ['project=' . $self->get_project_id()] + ); + return $buckets; +} + 1; __END__ @@ -408,7 +492,7 @@ Set GCP monitoring endpoint URL (Default: 'https://monitoring.googleapis.com/v3' =item B<--scope-endpoint> -Set GCP scope endpoint URL (Default: 'https://www.googleapis.com/auth/monitoring.read') +Set GCP scope endpoint URL (Default: 'https://www.googleapis.com/auth/cloud-platform') =item B<--zeroed> diff --git a/cloud/google/gcp/database/mysql/mode/discovery.pm b/cloud/google/gcp/database/mysql/mode/discovery.pm new file mode 100644 index 000000000..479d0e629 --- /dev/null +++ b/cloud/google/gcp/database/mysql/mode/discovery.pm @@ -0,0 +1,109 @@ +# +# 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::google::gcp::database::mysql::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 $instances = $options{custom}->gcp_list_cloudsql_instances(); + foreach my $instance (@$instances) { + next if ($instance->{databaseVersion} !~ /mysql/i); + my $item = {}; + $item->{name} = $instance->{name}; + $item->{version} = $instance->{databaseVersion}; + $item->{state} = $instance->{state}; + $item->{region} = $instance->{region}; + $item->{tier} = $instance->{settings}->{tier}; + $item->{instance_type} = $instance->{settings}->{instance_type}; + $item->{ip_addresses} = []; + foreach (@{$instance->{ipAddresses}}) { + push @{$item->{ip_addresses}}, { ip_address => $_->{ipAddress}, type => $_->{type} }; + } + push @$disco_data, $item; + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = scalar(@$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 + +MySQL instance discovery. + +=over 8 + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/cloud/google/gcp/database/mysql/plugin.pm b/cloud/google/gcp/database/mysql/plugin.pm index 8fb7b8f8e..916494045 100644 --- a/cloud/google/gcp/database/mysql/plugin.pm +++ b/cloud/google/gcp/database/mysql/plugin.pm @@ -31,11 +31,12 @@ sub new { $self->{version} = '0.1'; $self->{modes} = { - 'cpu' => 'cloud::google::gcp::database::common::mode::cpu', - 'innodb' => 'cloud::google::gcp::database::mysql::mode::innodb', - 'network' => 'cloud::google::gcp::database::common::mode::network', - 'queries' => 'cloud::google::gcp::database::mysql::mode::queries', - 'storage' => 'cloud::google::gcp::database::common::mode::storage' + 'cpu' => 'cloud::google::gcp::database::common::mode::cpu', + 'discovery' => 'cloud::google::gcp::database::mysql::mode::discovery', + 'innodb' => 'cloud::google::gcp::database::mysql::mode::innodb', + 'network' => 'cloud::google::gcp::database::common::mode::network', + 'queries' => 'cloud::google::gcp::database::mysql::mode::queries', + 'storage' => 'cloud::google::gcp::database::common::mode::storage' }; $self->{custom_modes}->{api} = 'cloud::google::gcp::custom::api'; diff --git a/cloud/google/gcp/storage/mode/discovery.pm b/cloud/google/gcp/storage/mode/discovery.pm new file mode 100644 index 000000000..3198128b5 --- /dev/null +++ b/cloud/google/gcp/storage/mode/discovery.pm @@ -0,0 +1,105 @@ +# +# 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::google::gcp::storage::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 $buckets = $options{custom}->gcp_list_storage_buckets(); + foreach my $bucket (@$buckets) { + my $item = {}; + $item->{id} = $bucket->{id}; + $item->{name} = $bucket->{name}; + $item->{project_number} = $bucket->{projectNumber}; + $item->{location} = $bucket->{location}; + $item->{location_type} = $bucket->{locationType}; + $item->{storage_class} = $bucket->{storageClass}; + + push @$disco_data, $item; + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = scalar(@$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 + +Storage discovery. + +=over 8 + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/cloud/google/gcp/storage/plugin.pm b/cloud/google/gcp/storage/plugin.pm index 5117752aa..5a98e4293 100644 --- a/cloud/google/gcp/storage/plugin.pm +++ b/cloud/google/gcp/storage/plugin.pm @@ -31,7 +31,8 @@ sub new { $self->{version} = '0.1'; $self->{modes} = { - 'bucket' => 'cloud::google::gcp::storage::mode::bucket' + 'bucket' => 'cloud::google::gcp::storage::mode::bucket', + 'discovery' => 'cloud::google::gcp::storage::mode::discovery' }; $self->{custom_modes}->{api} = 'cloud::google::gcp::custom::api';