From d113842850b7560f32a199f7cbfdb3c6e9947e61 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Tue, 21 Aug 2018 14:14:20 +0000 Subject: [PATCH] add microsoft azure plugin, wip (#1097) --- .../cloud/azure/compute/mode/cpu.pm | 233 +++++++++ .../cloud/azure/compute/mode/diskio.pm | 323 +++++++++++++ .../cloud/azure/compute/mode/listresources.pm | 129 +++++ .../cloud/azure/compute/mode/listvms.pm | 121 +++++ .../cloud/azure/compute/mode/network.pm | 278 +++++++++++ .../cloud/azure/compute/mode/vmsizes.pm | 262 +++++++++++ .../cloud/azure/compute/mode/vmsstate.pm | 237 ++++++++++ .../cloud/azure/compute/plugin.pm | 55 +++ centreon-plugins/cloud/azure/custom/azcli.pm | 445 ++++++++++++++++++ .../cloud/azure/monitor/mode/getmetrics.pm | 231 +++++++++ .../cloud/azure/monitor/plugin.pm | 50 ++ .../cloud/azure/network/mode/listresources.pm | 129 +++++ .../cloud/azure/network/mode/traffic.pm | 324 +++++++++++++ .../cloud/azure/network/plugin.pm | 50 ++ .../azure/resources/mode/deploymentsstatus.pm | 237 ++++++++++ .../cloud/azure/resources/mode/items.pm | 184 ++++++++ .../cloud/azure/resources/mode/listgroups.pm | 112 +++++ .../azure/resources/mode/listresources.pm | 129 +++++ .../cloud/azure/resources/plugin.pm | 52 ++ .../azure/storage/mode/accountusedcapacity.pm | 205 ++++++++ .../cloud/azure/storage/mode/blobcapacity.pm | 207 ++++++++ .../azure/storage/mode/blobcontainercount.pm | 206 ++++++++ .../cloud/azure/storage/mode/blobcount.pm | 206 ++++++++ .../cloud/azure/storage/mode/filecapacity.pm | 207 ++++++++ .../cloud/azure/storage/mode/filecount.pm | 206 ++++++++ .../azure/storage/mode/filesharecount.pm | 206 ++++++++ .../cloud/azure/storage/mode/listresources.pm | 129 +++++ .../cloud/azure/storage/mode/queuecapacity.pm | 207 ++++++++ .../cloud/azure/storage/mode/queuecount.pm | 206 ++++++++ .../azure/storage/mode/queuemessagecount.pm | 206 ++++++++ .../cloud/azure/storage/mode/tablecapacity.pm | 207 ++++++++ .../cloud/azure/storage/mode/tablecount.pm | 206 ++++++++ .../azure/storage/mode/tableentitycount.pm | 206 ++++++++ .../storage/mode/transactionsavailability.pm | 222 +++++++++ .../azure/storage/mode/transactionscount.pm | 283 +++++++++++ .../azure/storage/mode/transactionslatency.pm | 236 ++++++++++ .../storage/mode/transactionsthroughput.pm | 295 ++++++++++++ .../cloud/azure/storage/plugin.pm | 66 +++ 38 files changed, 7493 insertions(+) create mode 100644 centreon-plugins/cloud/azure/compute/mode/cpu.pm create mode 100644 centreon-plugins/cloud/azure/compute/mode/diskio.pm create mode 100644 centreon-plugins/cloud/azure/compute/mode/listresources.pm create mode 100644 centreon-plugins/cloud/azure/compute/mode/listvms.pm create mode 100644 centreon-plugins/cloud/azure/compute/mode/network.pm create mode 100644 centreon-plugins/cloud/azure/compute/mode/vmsizes.pm create mode 100644 centreon-plugins/cloud/azure/compute/mode/vmsstate.pm create mode 100644 centreon-plugins/cloud/azure/compute/plugin.pm create mode 100644 centreon-plugins/cloud/azure/custom/azcli.pm create mode 100644 centreon-plugins/cloud/azure/monitor/mode/getmetrics.pm create mode 100644 centreon-plugins/cloud/azure/monitor/plugin.pm create mode 100644 centreon-plugins/cloud/azure/network/mode/listresources.pm create mode 100644 centreon-plugins/cloud/azure/network/mode/traffic.pm create mode 100644 centreon-plugins/cloud/azure/network/plugin.pm create mode 100644 centreon-plugins/cloud/azure/resources/mode/deploymentsstatus.pm create mode 100644 centreon-plugins/cloud/azure/resources/mode/items.pm create mode 100644 centreon-plugins/cloud/azure/resources/mode/listgroups.pm create mode 100644 centreon-plugins/cloud/azure/resources/mode/listresources.pm create mode 100644 centreon-plugins/cloud/azure/resources/plugin.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/accountusedcapacity.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/blobcapacity.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/blobcontainercount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/blobcount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/filecapacity.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/filecount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/filesharecount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/listresources.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/queuecapacity.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/queuecount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/queuemessagecount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/tablecapacity.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/tablecount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/tableentitycount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/transactionsavailability.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/transactionscount.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/transactionslatency.pm create mode 100644 centreon-plugins/cloud/azure/storage/mode/transactionsthroughput.pm create mode 100644 centreon-plugins/cloud/azure/storage/plugin.pm diff --git a/centreon-plugins/cloud/azure/compute/mode/cpu.pm b/centreon-plugins/cloud/azure/compute/mode/cpu.pm new file mode 100644 index 000000000..70343a588 --- /dev/null +++ b/centreon-plugins/cloud/azure/compute/mode/cpu.pm @@ -0,0 +1,233 @@ +# +# Copyright 2018 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::azure::compute::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All CPU metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('CPU Credits Remaining', 'CPU Credits Consumed') { + my $metric_perf = lc($metric); + my $metric_label = lc($metric); + $metric_perf =~ s/ /_/g; + $metric_label =~ s/ /-/g; + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_perf . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %.2f', + perfdatas => [ + { label => $metric_perf . '_' . $aggregation, value => $metric_perf . '_' . $aggregation . '_absolute', + template => '%.2f', unit => 'credits', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + foreach my $metric ('Percentage CPU') { + my $metric_perf = lc($metric); + my $metric_label = lc($metric); + $metric_perf =~ s/ /_/g; + $metric_label =~ s/ /-/g; + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_perf . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %.2f %%', + perfdatas => [ + { label => $metric_perf . '_' . $aggregation, value => $metric_perf . '_' . $aggregation . '_absolute', + template => '%.2f', unit => '%', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0, max => 100 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "filter-metric:s" => { name => 'filter_metric' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Compute'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Compute\/.*\/.*$/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT5M"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('CPU Credits Remaining', 'CPU Credits Consumed', 'Percentage CPU') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + $resource_name = $1 if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Compute\/.*\/(.*)$/); + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check compute resources CPU metrics. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::plugin --custommode=azcli --mode=cpu +--resource=MYSQLINSTANCE --resource-group=MYHOSTGROUP --resource-type=virtualMachines +--filter-metric='Credits' --aggregation='average' --critical-cpu-credits-remaining-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::plugin --custommode=azcli --mode=cpu +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Compute/virtualMachines/xxx' +--filter-metric='Credits' --aggregation='average' --critical-cpu-credits-remaining-average='10' --verbose + +Default aggregation: 'average' / All aggregations are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'virtualMachines', 'xx'). + +=item B<--filter-metric> + +Filter metrics (Can be: 'CPU Credits Remaining', 'CPU Credits Consumed', +'Percentage CPU') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'cpu-credits-remaining', 'cpu-credits-consumed', +'percentage-cpu', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'cpu-credits-remaining', 'cpu-credits-consumed', +'percentage-cpu', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/compute/mode/diskio.pm b/centreon-plugins/cloud/azure/compute/mode/diskio.pm new file mode 100644 index 000000000..a319d4281 --- /dev/null +++ b/centreon-plugins/cloud/azure/compute/mode/diskio.pm @@ -0,0 +1,323 @@ +# +# Copyright 2018 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::azure::compute::mode::diskio; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; + $self->{result_values}->{metric_perf} = lc($options{extra_options}->{metric_perf}); + $self->{result_values}->{metric_label} = lc($options{extra_options}->{metric_label}); + $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; + $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric_perf} . '_' . $self->{result_values}->{stat}}; + $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{metric_perf} =~ s/\//_/g; + $self->{result_values}->{metric_label} =~ s/\//-/g; + return 0; +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_usage_output { + my ($self, %options) = @_; + my $msg = ""; + + if (defined($instance_mode->{option_results}->{per_sec})) { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; + } else { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit; + } + return $msg; +} + +sub custom_ops_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => 'ops/s', + value => sprintf("%.2f", $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_ops_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s: %.2f ops/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); + + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All disk metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('Disk Read Bytes', 'Disk Write Bytes') { + my $metric_perf = lc($metric); + my $metric_label = lc($metric); + $metric_perf =~ s/ /_/g; + $metric_label =~ s/ /-/g; + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_perf . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + foreach my $metric ('Disk Read Operations/Sec', 'Disk Write Operations/Sec') { + my $metric_perf = lc($metric); + my $metric_label = lc($metric); + $metric_perf =~ s/ /_/g; + $metric_label =~ s/ /-/g; + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_perf . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric }, + closure_custom_output => $self->can('custom_ops_output'), + closure_custom_perfdata => $self->can('custom_ops_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Compute'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Compute\/.*\/.*$/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT5M"; + + $self->{az_aggregations} = ['Total', 'Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('Disk Read Bytes', 'Disk Write Bytes', 'Disk Read Operations/Sec', + 'Disk Write Operations/Sec') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{az_metrics}}, $metric; + } + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + $resource_name = $1 if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Compute\/.*\/(.*)$/); + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{timeframe} = $self->{az_timeframe}; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check compute resources disk IO metrics. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::plugin --custommode=azcli --mode=diskio +--resource=MYSQLINSTANCE --resource-group=MYHOSTGROUP --resource-type=virtualMachines +--aggregation='total' --aggregation='average' --critical-disk-write-bytes-total='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::plugin --custommode=azcli --mode=diskio +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Compute/virtualMachines/xxx' +--aggregation='total' --aggregation='average' --critical-disk-write-bytes-total='10' --verbose + +Default aggregation: 'total', 'average' / All aggregations are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'virtualMachines', 'xx'). + +=item B<--filter-metric> + +Filter metrics (Can be: 'Disk Read Bytes', 'Disk Write Bytes', +'Disk Read Operations/Sec', 'Disk Write Operations/Sec') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'disk-read-bytes', 'disk-write-bytes', 'disk-read-operations-sec', +'disk-write-operations-sec', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'disk-read-bytes', 'disk-write-bytes', 'disk-read-operations-sec', +'disk-write-operations-sec', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--per-sec> + +Change the data to be unit/sec. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/compute/mode/listresources.pm b/centreon-plugins/cloud/azure/compute/mode/listresources.pm new file mode 100644 index 000000000..9dc921c30 --- /dev/null +++ b/centreon-plugins/cloud/azure/compute/mode/listresources.pm @@ -0,0 +1,129 @@ +# +# Copyright 2018 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::azure::compute::mode::listresources; + +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; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type', default => 'virtualMachines' }, + "location:s" => { name => 'location' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{resources} = $options{custom}->azure_list_resources( + namespace => 'Microsoft.Compute', + resource_type => $self->{option_results}->{resource_type}, + location => $self->{option_results}->{location}, + resource_group => $self->{option_results}->{resource_group} + ); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $resource (@{$self->{resources}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $resource->{name} !~ /$self->{option_results}->{filter_name}/); + $resource->{type} =~ s/Microsoft.Compute\///g; + $self->{output}->output_add(long_msg => sprintf("[name = %s][resourcegroup = %s][location = %s][id = %s][type = %s]", + $resource->{name}, $resource->{resourceGroup}, $resource->{location}, $resource->{id}, $resource->{type})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List resources:'); + $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 => ['name', 'resourcegroup', 'location', 'id', 'type']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $resource (@{$self->{resources}}) { + $resource->{type} =~ s/Microsoft.Compute\///g; + $self->{output}->add_disco_entry( + name => $resource->{name}, + resourcegroup => $resource->{resourceGroup}, + location => $resource->{location}, + id => $resource->{id}, + type => $resource->{type}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List compute resources. + +=over 8 + +=item B<--resource-group> + +Set resource group. + +=item B<--resource-type> + +Set resource type (Default: 'virtualMachines'). + +=item B<--location> + +Set resource location. + +=item B<--filter-name> + +Filter resource name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/compute/mode/listvms.pm b/centreon-plugins/cloud/azure/compute/mode/listvms.pm new file mode 100644 index 000000000..eddfe4dc5 --- /dev/null +++ b/centreon-plugins/cloud/azure/compute/mode/listvms.pm @@ -0,0 +1,121 @@ +# +# Copyright 2018 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::azure::compute::mode::listvms; + +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; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{vms} = $options{custom}->azure_list_vms( + resource_group => $self->{option_results}->{resource_group}, + show_details => 1 + ); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $vm (@{$self->{vms}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $vm->{name} !~ /$self->{option_results}->{filter_name}/); + $self->{output}->output_add(long_msg => sprintf("[name = %s][computername = %s][resourcegroup = %s]" . + "[location = %s][vmid = %s][vmsize = %s][os = %s][state = %s]", + $vm->{name}, (defined($vm->{osProfile}->{computerName})) ? $vm->{osProfile}->{computerName} : "-", + $vm->{resourceGroup}, $vm->{location}, $vm->{vmId}, $vm->{hardwareProfile}->{vmSize}, + $vm->{storageProfile}->{osDisk}->{osType}, $vm->{powerState})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List vitual machines:'); + $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 => ['name', 'computername', 'resourcegroup', 'location', 'vmid', 'vmsize', 'os', 'state']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $vm (@{$self->{vms}}) { + $self->{output}->add_disco_entry( + name => $vm->{name}, + computername => (defined($vm->{osProfile}->{computerName})) ? $vm->{osProfile}->{computerName} : "-", + resourcegroup => $vm->{resourceGroup}, + location => $vm->{location}, + vmid => $vm->{vmId}, + vmsize => $vm->{hardwareProfile}->{vmSize}, + os => $vm->{storageProfile}->{osDisk}->{osType}, + state => $vm->{powerState}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List vitual machines. + +=over 8 + +=item B<--resource-group> + +Set resource group (Optional). + +=item B<--filter-name> + +Filter resource name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/compute/mode/network.pm b/centreon-plugins/cloud/azure/compute/mode/network.pm new file mode 100644 index 000000000..25baf4134 --- /dev/null +++ b/centreon-plugins/cloud/azure/compute/mode/network.pm @@ -0,0 +1,278 @@ +# +# Copyright 2018 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::azure::compute::mode::network; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; + $self->{result_values}->{metric_perf} = lc($options{extra_options}->{metric_perf}); + $self->{result_values}->{metric_label} = lc($options{extra_options}->{metric_label}); + $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; + $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric_perf} . '_' . $self->{result_values}->{stat}}; + $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_traffic_output { + my ($self, %options) = @_; + my $msg = ""; + + if (defined($instance_mode->{option_results}->{per_sec})) { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; + } else { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit; + } + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All network metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('Network In', 'Network Out') { + my $metric_perf = lc($metric); + my $metric_label = lc($metric); + $metric_perf =~ s/ /_/g; + $metric_label =~ s/ /-/g; + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_perf . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric }, + closure_custom_output => $self->can('custom_traffic_output'), + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Compute'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Compute\/.*\/.*$/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT5M"; + + $self->{az_aggregations} = ['Total']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('Network In', 'Network Out') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{az_metrics}}, $metric; + } + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + $resource_name = $1 if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Compute\/.*\/(.*)$/); + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{timeframe} = $self->{az_timeframe}; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check compute resources network metrics. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::plugin --custommode=azcli --mode=network +--resource=MYSQLINSTANCE --resource-group=MYHOSTGROUP --resource-type=virtualMachines +--aggregation='total' --critical-network-out-total='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::compute::plugin --custommode=azcli --mode=network +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Compute/virtualMachines/xxx' +--aggregation='total' --critical-network-out-total='10' --verbose + +Default aggregation: 'total' / All aggregations are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'virtualMachines', 'xx'). + +=item B<--filter-metric> + +Filter metrics (Can be: 'Network In', 'Network Out') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'network-in', 'network-out', +$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'network-in', 'network-out', +$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--per-sec> + +Change the data to be unit/sec. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/compute/mode/vmsizes.pm b/centreon-plugins/cloud/azure/compute/mode/vmsizes.pm new file mode 100644 index 000000000..0a32c3e87 --- /dev/null +++ b/centreon-plugins/cloud/azure/compute/mode/vmsizes.pm @@ -0,0 +1,262 @@ +# +# Copyright 2018 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::azure::compute::mode::vmsizes; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my %vm_types = ( + 'general' => ['Standard_B1s', 'Standard_B1ms', 'Standard_B2s', 'Standard_B2ms', 'Standard_B4ms', 'Standard_B8ms', + 'Standard_D2s_v3', 'Standard_D4s_v3', 'Standard_D8s_v3', 'Standard_D16s_v3', 'Standard_D32s_v3', + 'Standard_D64s_v3', 'Standard_D2_v3', 'Standard_D4_v3', 'Standard_D8_v3', 'Standard_D16_v3', 'Standard_D32_v3', + 'Standard_D64_v3', 'Standard_DS1_v2', 'Standard_DS2_v2', 'Standard_DS3_v2', 'Standard_DS4_v2', 'Standard_DS5_v2', + 'Standard_D1_v2', 'Standard_D2_v2', 'Standard_D3_v2', 'Standard_D4_v2', 'Standard_D5_v2', 'Standard_A1_v2', + 'Standard_A2_v2', 'Standard_A4_v2', 'Standard_A8_v2', 'Standard_A2m_v2', 'Standard_A4m_v2', 'Standard_A8m_v2'], + 'compute' => ['Standard_F2s_v2', 'Standard_F4s_v2', 'Standard_F8s_v2', 'Standard_F16s_v2', 'Standard_F32s_v2', + 'Standard_F64s_v2', 'Standard_F72s_v2', 'Standard_F1s', 'Standard_F2s', 'Standard_F4s', 'Standard_F8s', + 'Standard_F16s', 'Standard_F1', 'Standard_F2', 'Standard_F4', 'Standard_F8', 'Standard_F16'], + 'memory' => ['Standard_E2s_v3', 'Standard_E4s_v3', 'Standard_E8s_v3', 'Standard_E16s_v3', 'Standard_E32s_v3', + 'Standard_E64s_v3', 'Standard_E64is_v3', 'Standard_E2_v3', 'Standard_E4_v3', 'Standard_E8_v3', 'Standard_E16_v3', + 'Standard_E32_v3', 'Standard_E64_v3', 'Standard_E64i_v3', 'Standard_M8ms3', 'Standard_M16ms', 'Standard_M32ts', + 'Standard_M32ls', 'Standard_M32ms', 'Standard_M64s', 'Standard_M64ls', 'Standard_M64ms', 'Standard_M128s', + 'Standard_M128ms', 'Standard_M64', 'Standard_M64m', 'Standard_M128', 'Standard_M128m', 'Standard_GS1', + 'Standard_GS2', 'Standard_GS3', 'Standard_GS4', 'Standard_GS5', 'Standard_G1', 'Standard_G2', 'Standard_G3', + 'Standard_G4', 'Standard_G5', 'Standard_DS11_v2', 'Standard_DS12_v2', 'Standard_DS13_v2', 'Standard_DS14_v2', + 'Standard_DS15_v2', 'Standard_D11_v2', 'Standard_D12_v2', 'Standard_D13_v2', 'Standard_D14_v2', 'Standard_D15_v2'], + 'storage' => ['Standard_L4s', 'Standard_L8s', 'Standard_L16s', 'Standard_L32s'], + 'gpu' => ['Standard_NC6', 'Standard_NC12', 'Standard_NC24', 'Standard_NC24r', 'Standard_NC6s_v2', 'Standard_NC12s_v2', + 'Standard_NC24s_v2', 'Standard_NC24rs_v2', 'Standard_NC6s_v3', 'Standard_NC12s_v3', 'Standard_NC24s_v3', + 'Standard_NC24rs_v3', 'Standard_ND6s', 'Standard_ND12s', 'Standard_ND24s', 'Standard_ND24rs', 'Standard_NV6', + 'Standard_NV12', 'Standard_NV24'], + 'high_performance' => ['Standard_H8', 'Standard_H16', 'Standard_H8m', 'Standard_H16m', 'Standard_H16r', + 'Standard_H16mr'], +); + +sub prefix_general_output { + my ($self, %options) = @_; + + return "Virtual machine type 'General purpose' resource sizes count "; +} + +sub prefix_compute_output { + my ($self, %options) = @_; + + return "Virtual machine type 'Compute optimized' resource sizes count "; +} + +sub prefix_memory_output { + my ($self, %options) = @_; + + return "Virtual machine type 'Memory optimized' resource sizes count "; +} + +sub prefix_storage_output { + my ($self, %options) = @_; + + return "Virtual machine type 'Storage optimized' resource sizes count "; +} + +sub prefix_gpu_output { + my ($self, %options) = @_; + + return "Virtual machine type 'GPU' resource sizes count "; +} + +sub prefix_high_performance_output { + my ($self, %options) = @_; + + return "Virtual machine type 'High performance compute' resource sizes count "; +} + +sub set_counters { + my ($self, %options) = @_; + + foreach my $type (keys %vm_types) { + my $counter = { name => $type, type => 0, cb_prefix_output => 'prefix_' . $type . '_output', skipped_code => { -10 => 1 } }; + + push @{$self->{maps_counters_type}}, $counter; + + $self->{maps_counters}->{$type} = []; + + foreach my $size (@{$vm_types{$type}}) { + my $perf = lc($size); + my $label = lc($size); + $label =~ s/_/-/g; + my $entry = { label => $label, set => { + key_values => [ { name => $size } ], + output_template => $size . ": %s", + perfdatas => [ + { label => $perf, value => $size . '_absolute', template => '%d', min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{$type}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "filter-type:s" => { name => 'filter_type' }, + "filter-size:s" => { name => 'filter_size' }, + "running" => { name => 'running' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + foreach my $type (keys %vm_types) { + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $type !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => sprintf("skipping type '%s'", $type), debug => 1); + $self->{maps_counters}->{$type} = undef; + } else { + foreach my $size (@{$vm_types{$type}}) { + if (defined($self->{option_results}->{filter_size}) && $self->{option_results}->{filter_size} ne '' && + $size !~ /$self->{option_results}->{filter_size}/) { + next; + } + $self->{$type}->{$size} = 0; + } + } + } + + my $vms = $options{custom}->azure_list_vms(resource_group => $self->{option_results}->{resource_group}, show_details => 1); + + foreach my $vm (@{$vms}) { + next if (defined($self->{option_results}->{running}) && $vm->{powerState} !~ /running/); + if (defined($self->{option_results}->{filter_size}) && $self->{option_results}->{filter_size} ne '' && + $vm->{hardwareProfile}->{vmSize} !~ /$self->{option_results}->{filter_size}/) { + $self->{output}->output_add(long_msg => sprintf("skipping size '%s'", $vm->{hardwareProfile}->{vmSize}), debug => 1); + next; + } + foreach my $type (keys %vm_types) { + next if (!defined($self->{maps_counters}->{$type})); + $self->{$type}->{$vm->{hardwareProfile}->{vmSize}}++ if (map(/$vm->{hardwareProfile}->{vmSize}/, @{$vm_types{$type}})); + } + } + + if (scalar(keys %{$self->{general}}) <= 0 && scalar(keys %{$self->{compute}}) <= 0 && scalar(keys %{$self->{memory}}) <= 0 && + scalar(keys %{$self->{storage}}) <= 0 && scalar(keys %{$self->{gpu}}) <= 0 && scalar(keys %{$self->{high_performance}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No result matched with applied filters."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +List virtual machines resource sizes. + +=over 8 + +=item B<--resource-group> + +Set resource group (Optional). + +=item B<--filter-type> + +Filter by virtual machine type (regexp) +(Can be: 'general', 'compute', 'memory', 'storage', 'gpu', 'high_performance') + +=item B<--filter-size> + +Filter by virtual machine size (regexp) + +=item B<--warning-*> + +Threshold warning. +Can be: 'standard-b1s', 'standard-b1ms', 'standard-b2s', 'standard-b2ms', 'standard-b4ms', 'standard-b8ms', +'standard-d2s-v3', 'standard-d4s-v3', 'standard-d8s-v3', 'standard-d16s-v3', 'standard-d32s-v3', +'standard-d64s-v3', 'standard-d2-v3', 'standard-d4-v3', 'standard-d8-v3', 'standard-d16-v3', 'standard-d32-v3', +'standard-d64-v3', 'standard-ds1-v2', 'standard-ds2-v2', 'standard-ds3-v2', 'standard-ds4-v2', 'standard-ds5-v2', +'standard-d1-v2', 'standard-d2-v2', 'standard-d3-v2', 'standard-d4-v2', 'standard-d5-v2', 'standard-a1-v2', +'standard-a2-v2', 'standard-a4-v2', 'standard-a8-v2', 'standard-a2m-v2', 'standard-a4m-v2', 'standard-a8m-v2', +'standard-f2s-v2', 'standard-f4s-v2', 'standard-f8s-v2', 'standard-f16s-v2', 'standard-f32s-v2', +'standard-f64s-v2', 'standard-f72s-v2', 'standard-f1s', 'standard-f2s', 'standard-f4s', 'standard-f8s', +'standard-f16s', 'standard-f1', 'standard-f2', 'standard-f4', 'standard-f8', 'standard-f16', +'standard-e2s-v3', 'standard-e4s-v3', 'standard-e8s-v3', 'standard-e16s-v3', 'standard-e32s-v3', +'standard-e64s-v3', 'standard-e64is-v3', 'standard-e2-v3', 'standard-e4-v3', 'standard-e8-v3', 'standard-e16-v3', +'standard-e32-v3', 'standard-e64-v3', 'standard-e64i-v3', 'standard-m8ms3', 'standard-m16ms', 'standard-m32ts', +'standard-m32ls', 'standard-m32ms', 'standard-m64s', 'standard-m64ls', 'standard-m64ms', 'standard-m128s', +'standard-m128ms', 'standard-m64', 'standard-m64m', 'standard-m128', 'standard-m128m', 'standard-gs1', +'standard-gs2', 'standard-gs3', 'standard-gs4', 'standard-gs5', 'standard-g1', 'standard-g2', 'standard-g3', +'standard-g4', 'standard-g5', 'standard-ds11-v2', 'standard-ds12-v2', 'standard-ds13-v2', 'standard-ds14-v2', +'standard-ds15-v2', 'standard-d11-v2', 'standard-d12-v2', 'standard-d13-v2', 'standard-d14-v2', 'standard-d15-v2', +'standard-l4s', 'standard-l8s', 'standard-l16s', 'standard-l32s', 'standard-nc6', 'standard-nc12', 'standard-nc24', +'standard-nc24r', 'standard-nc6s-v2', 'standard-nc12s-v2', 'standard-nc24s-v2', 'standard-nc24rs-v2', 'standard-nc6s-v3', +'standard-nc12s-v3', 'standard-nc24s-v3', 'standard-nc24rs-v3', 'standard-nd6s', 'standard-nd12s', 'standard-nd24s', +'standard-nd24rs', 'standard-nv6', 'standard-nv12', 'standard-nv24','standard-h8', 'standard-h16', 'standard-h8m', +'standard-h16m', 'standard-h16r', 'standard-h16mr'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'standard-b1s', 'standard-b1ms', 'standard-b2s', 'standard-b2ms', 'standard-b4ms', 'standard-b8ms', +'standard-d2s-v3', 'standard-d4s-v3', 'standard-d8s-v3', 'standard-d16s-v3', 'standard-d32s-v3', +'standard-d64s-v3', 'standard-d2-v3', 'standard-d4-v3', 'standard-d8-v3', 'standard-d16-v3', 'standard-d32-v3', +'standard-d64-v3', 'standard-ds1-v2', 'standard-ds2-v2', 'standard-ds3-v2', 'standard-ds4-v2', 'standard-ds5-v2', +'standard-d1-v2', 'standard-d2-v2', 'standard-d3-v2', 'standard-d4-v2', 'standard-d5-v2', 'standard-a1-v2', +'standard-a2-v2', 'standard-a4-v2', 'standard-a8-v2', 'standard-a2m-v2', 'standard-a4m-v2', 'standard-a8m-v2', +'standard-f2s-v2', 'standard-f4s-v2', 'standard-f8s-v2', 'standard-f16s-v2', 'standard-f32s-v2', +'standard-f64s-v2', 'standard-f72s-v2', 'standard-f1s', 'standard-f2s', 'standard-f4s', 'standard-f8s', +'standard-f16s', 'standard-f1', 'standard-f2', 'standard-f4', 'standard-f8', 'standard-f16', +'standard-e2s-v3', 'standard-e4s-v3', 'standard-e8s-v3', 'standard-e16s-v3', 'standard-e32s-v3', +'standard-e64s-v3', 'standard-e64is-v3', 'standard-e2-v3', 'standard-e4-v3', 'standard-e8-v3', 'standard-e16-v3', +'standard-e32-v3', 'standard-e64-v3', 'standard-e64i-v3', 'standard-m8ms3', 'standard-m16ms', 'standard-m32ts', +'standard-m32ls', 'standard-m32ms', 'standard-m64s', 'standard-m64ls', 'standard-m64ms', 'standard-m128s', +'standard-m128ms', 'standard-m64', 'standard-m64m', 'standard-m128', 'standard-m128m', 'standard-gs1', +'standard-gs2', 'standard-gs3', 'standard-gs4', 'standard-gs5', 'standard-g1', 'standard-g2', 'standard-g3', +'standard-g4', 'standard-g5', 'standard-ds11-v2', 'standard-ds12-v2', 'standard-ds13-v2', 'standard-ds14-v2', +'standard-ds15-v2', 'standard-d11-v2', 'standard-d12-v2', 'standard-d13-v2', 'standard-d14-v2', 'standard-d15-v2', +'standard-l4s', 'standard-l8s', 'standard-l16s', 'standard-l32s', 'standard-nc6', 'standard-nc12', 'standard-nc24', +'standard-nc24r', 'standard-nc6s-v2', 'standard-nc12s-v2', 'standard-nc24s-v2', 'standard-nc24rs-v2', 'standard-nc6s-v3', +'standard-nc12s-v3', 'standard-nc24s-v3', 'standard-nc24rs-v3', 'standard-nd6s', 'standard-nd12s', 'standard-nd24s', +'standard-nd24rs', 'standard-nv6', 'standard-nv12', 'standard-nv24','standard-h8', 'standard-h16', 'standard-h8m', +'standard-h16m', 'standard-h16r', 'standard-h16mr'. + +=item B<--running> + +Only check running virtual machines. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/compute/mode/vmsstate.pm b/centreon-plugins/cloud/azure/compute/mode/vmsstate.pm new file mode 100644 index 000000000..9ad7b1782 --- /dev/null +++ b/centreon-plugins/cloud/azure/compute/mode/vmsstate.pm @@ -0,0 +1,237 @@ +# +# Copyright 2018 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::azure::compute::mode::vmsstate; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('state: %s', $self->{result_values}->{state}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total vitual machines "; +} + +sub prefix_vm_output { + my ($self, %options) = @_; + + return "Virtual machine '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'vms', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All virtual machines are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-running', set => { + key_values => [ { name => 'running' } ], + output_template => "running : %s", + perfdatas => [ + { label => 'total_running', value => 'running_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-stopped', set => { + key_values => [ { name => 'stopped' } ], + output_template => "stopped : %s", + perfdatas => [ + { label => 'total_stopped', value => 'stopped_absolute', template => '%d', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{vms} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { + running => 0, stopped => 0, + }; + $self->{vms} = {}; + my $vms = $options{custom}->azure_list_vms(resource_group => $self->{option_results}->{resource_group}, show_details => 1); + foreach my $vm (@{$vms}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $vm->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $vm->{name} . "': no matching filter.", debug => 1); + next; + } + + $self->{vms}->{$vm->{id}} = { + display => $vm->{name}, + state => $vm->{powerState}, + }; + + foreach my $state (keys %{$self->{global}}) { + $self->{global}->{$state}++ if ($vm->{powerState} =~ /$state/); + } + } + + if (scalar(keys %{$self->{vms}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No virtual machines found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check virtual machines status. + +Example: +perl centreon_plugins.pl --plugin=cloud::azure::compute::plugin --custommode=azcli --mode=vms-state +--filter-name='.*' --filter-counters='^total-running$' --critical-total-running='10' --verbose + +=over 8 + +=item B<--resource-group> + +Set resource group (Optional). + +=item B<--filter-name> + +Filter resource name (Can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-running$' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{state}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{state}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-running', 'total-stopped'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-running', 'total-stopped'. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/compute/plugin.pm b/centreon-plugins/cloud/azure/compute/plugin.pm new file mode 100644 index 000000000..4f7101ebe --- /dev/null +++ b/centreon-plugins/cloud/azure/compute/plugin.pm @@ -0,0 +1,55 @@ +# +# Copyright 2018 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::azure::compute::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} } = ( + 'cpu' => 'cloud::azure::compute::mode::cpu', + 'diskio' => 'cloud::azure::compute::mode::diskio', + 'list-resources' => 'cloud::azure::compute::mode::listresources', + 'list-vms' => 'cloud::azure::compute::mode::listvms', + 'network' => 'cloud::azure::compute::mode::network', + 'vm-sizes' => 'cloud::azure::compute::mode::vmsizes', + 'vms-state' => 'cloud::azure::compute::mode::vmsstate', + ); + + $self->{custom_modes}{azcli} = 'cloud::azure::custom::azcli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Azure compute provider. + +=cut diff --git a/centreon-plugins/cloud/azure/custom/azcli.pm b/centreon-plugins/cloud/azure/custom/azcli.pm new file mode 100644 index 000000000..6cdd3f144 --- /dev/null +++ b/centreon-plugins/cloud/azure/custom/azcli.pm @@ -0,0 +1,445 @@ +# +# Copyright 2018 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::azure::custom::azcli; + +use strict; +use warnings; +use DateTime; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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 => + { + "timeframe:s" => { name => 'timeframe' }, + "interval:s" => { name => 'interval' }, + "aggregation:s@" => { name => 'aggregation' }, + "zeroed" => { name => 'zeroed' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'az' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'AZCLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + if (defined($self->{option_results}->{aggregation})) { + foreach my $aggregation (@{$self->{option_results}->{aggregation}}) { + if ($aggregation !~ /average|maximum|minimum|total/i) { + $self->{output}->add_option_msg(short_msg => "Aggregation '" . $aggregation . "' is not handled"); + $self->{output}->option_exit(); + } + } + } + + return 0; +} + +sub azure_get_metrics_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "monitor metrics list --metrics '" . join('\' \'', @{$options{metrics}}) . "' --start-time $options{start_time} --end-time $options{end_time} " . + "--interval $options{interval} --aggregation '" . join('\' \'', @{$options{aggregations}}) . "' --output json --resource '$options{resource}' " . + "--resource-group '$options{resource_group}' --resource-type '$options{resource_type}' --resource-namespace '$options{resource_namespace}'"; + + return $cmd_options; +} + +sub azure_get_metrics { + my ($self, %options) = @_; + + my $results = {}; + my $start_time = DateTime->now->subtract(seconds => $options{timeframe})->iso8601.'Z'; + my $end_time = DateTime->now->iso8601.'Z'; + + my $cmd_options = $self->azure_get_metrics_set_cmd(%options, start_time => $start_time, end_time => $end_time); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options); + + my $raw_results; + my $command_line = $self->{option_results}->{command} . " " . $cmd_options; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + foreach my $metric (@{$raw_results->{value}}) { + my $metric_name = lc($metric->{name}->{value}); + $metric_name =~ s/ /_/g; + + $results->{$metric_name} = { points => 0 }; + foreach my $timeserie (@{$metric->{timeseries}}) { + foreach my $point (@{$timeserie->{data}}) { + if (defined($point->{average})) { + $results->{$metric_name}->{average} = 0 if (!defined($results->{$metric_name}->{average})); + $results->{$metric_name}->{average} += $point->{average}; + $results->{$metric_name}->{points}++; + } + if (defined($point->{minimum})) { + $results->{$metric_name}->{minimum} = $point->{minimum} + if (!defined($results->{$metric_name}->{minimum}) || $point->{minimum} < $results->{$metric_name}->{minimum}); + } + if (defined($point->{maximum})) { + $results->{$metric_name}->{maximum} = $point->{maximum} + if (!defined($results->{$metric_name}->{maximum}) || $point->{maximum} > $results->{$metric_name}->{maximum}); + } + if (defined($point->{total})) { + $results->{$metric_name}->{total} = 0 if (!defined($results->{$metric_name}->{total})); + $results->{$metric_name}->{total} += $point->{total}; + $results->{$metric_name}->{points}++; + } + } + } + + if (defined($results->{$metric_name}->{average})) { + $results->{$metric_name}->{average} /= $results->{$metric_name}->{points}; + } + } + + return $results, $raw_results, $command_line; +} + +sub azure_list_resources_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "resource list --namespace '$options{namespace}' --resource-type '$options{resource_type}' --output json"; + $cmd_options .= " --location '$options{location}'" if (defined($options{location}) && $options{location} ne ''); + $cmd_options .= " --resource-group '$options{resource_group}'" if (defined($options{resource_group}) && $options{resource_group} ne ''); + + return $cmd_options; +} + +sub azure_list_resources { + my ($self, %options) = @_; + + my $results = {}; + + my $cmd_options = $self->azure_list_resources_set_cmd(%options); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options); + + my $raw_results; + my $command_line = $self->{option_results}->{command} . " " . $cmd_options; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + +sub azure_list_vm_sizes_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "vm list-sizes --location '$options{location}' --output json"; + + return $cmd_options; +} + +sub azure_list_vm_sizes { + my ($self, %options) = @_; + + my $results = {}; + + my $cmd_options = $self->azure_list_vm_sizes_set_cmd(%options); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options); + + my $raw_results; + my $command_line = $self->{option_results}->{command} . " " . $cmd_options; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + +sub azure_list_vms_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "vm list --output json"; + $cmd_options .= " --resource-group '$options{resource_group}'" if (defined($options{resource_group}) && $options{resource_group} ne ''); + $cmd_options .= " --show-details" if (defined($options{show_details})); + + return $cmd_options; +} + +sub azure_list_vms { + my ($self, %options) = @_; + + my $results = {}; + + my $cmd_options = $self->azure_list_vms_set_cmd(%options); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options); + + my $raw_results; + my $command_line = $self->{option_results}->{command} . " " . $cmd_options; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + +sub azure_list_groups_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "group list --output json"; + + return $cmd_options; +} + +sub azure_list_groups { + my ($self, %options) = @_; + + my $results = {}; + + my $cmd_options = $self->azure_list_groups_set_cmd(%options); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options); + + my $raw_results; + my $command_line = $self->{option_results}->{command} . " " . $cmd_options; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + +sub azure_list_deployments_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "group deployment list --resource-group '$options{resource_group}' --output json"; + + return $cmd_options; +} + +sub azure_list_deployments { + my ($self, %options) = @_; + + my $results = {}; + + my $cmd_options = $self->azure_list_deployments_set_cmd(%options); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options); + + my $raw_results; + my $command_line = $self->{option_results}->{command} . " " . $cmd_options; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + +1; + +__END__ + +=head1 NAME + +Microsoft Azure CLI + +=head1 SYNOPSIS + +Microsoft Azure CLI 2.0 + +To install the Azure CLI 2.0 in a CentOS/RedHat environment : +# sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc +# sudo sh -c 'echo -e "[azure-cli]\nname=Azure CLI\nbaseurl=https://packages.microsoft.com/yumrepos/azure-cli\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/azure-cli.repo' +# yum install azure-cli +# az login -u -p +Go to https://aka.ms/devicelogin and enter the code given by the last command. + +For futher informations, visit https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest. + +=head1 AZCLI OPTIONS + +=over 8 + +=item B<--timeframe> + +Set timeframe in seconds (i.e. 3600 to check last hour). + +=item B<--interval> + +Set interval of the metric query (Can be : PT1M, PT5M, PT15M, PT30M, PT1H, PT6H, PT12H, PT24H). + +=item B<--aggregations> + +Set monitor aggregations (Can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--zeroed> + +Set metrics value to 0 if none. Usefull when Monitor +does not return value when not defined. + +=item B<--timeout> + +Set timeout in seconds (Default: 50). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'az'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: none). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/cloud/azure/monitor/mode/getmetrics.pm b/centreon-plugins/cloud/azure/monitor/mode/getmetrics.pm new file mode 100644 index 000000000..59a0c0f90 --- /dev/null +++ b/centreon-plugins/cloud/azure/monitor/mode/getmetrics.pm @@ -0,0 +1,231 @@ +# +# Copyright 2018 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::azure::monitor::mode::getmetrics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Data::Dumper; + +sub custom_metric_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => $self->{result_values}->{perf_label}, + value => $self->{result_values}->{value}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-metric'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-metric'), + ); + +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{value}, + threshold => [ { label => 'critical-metric', exit_litteral => 'critical' }, + { label => 'warning-metric', exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_metric_output { + my ($self, %options) = @_; + + my $msg = "Metric '" . $self->{result_values}->{label} . "' of resource '" . $self->{result_values}->{display} . "' value is " . $self->{result_values}->{value}; + return $msg; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_value'}; + $self->{result_values}->{label} = $options{new_datas}->{$self->{instance} . '_label'}; + $self->{result_values}->{aggregation} = $options{new_datas}->{$self->{instance} . '_aggregation'}; + $self->{result_values}->{perf_label} = $options{new_datas}->{$self->{instance} . '_perf_label'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metrics', type => 0 }, + ]; + + $self->{maps_counters}->{metrics} = [ + { label => 'metric', set => { + key_values => [ { name => 'value' }, { name => 'label' }, { name => 'aggregation' }, + { name => 'perf_label' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_output => $self->can('custom_metric_output'), + closure_custom_perfdata => $self->can('custom_metric_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "resource-namespace:s" => { name => 'resource_namespace' }, + "metric:s@" => { name => 'metric' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource} = $self->{option_results}->{resource}; + + if ($self->{az_resource} =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\..*\/.*\/.*$/) { + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + $self->{az_resource_namespace} = $self->{option_results}->{resource_namespace}; + } + + $self->{az_metrics} = []; + if (defined($self->{option_results}->{metric})) { + $self->{az_metrics} = $self->{option_results}->{metric}; + } + if (scalar(@{$self->{az_metrics}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "Need to specify --metric option."); + $self->{output}->option_exit(); + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1M"; + + $self->{az_aggregation} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregation} = []; + foreach my $aggregation (@{$self->{option_results}->{aggregation}}) { + if ($aggregation ne '') { + push @{$self->{az_aggregation}}, ucfirst(lc($aggregation)); + } + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($results, $raw_results, $command_line) = $options{custom}->azure_get_metrics( + resource => $self->{az_resource}, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregation}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + $self->{metrics} = {}; + foreach my $label (keys %{$results}) { + foreach my $aggregation (('minimum', 'maximum', 'average', 'total')) { + next if (!defined($results->{$label}->{$aggregation})); + + $self->{metrics} = { + display => $self->{az_resource}, + label => $label, + aggregation => $aggregation, + value => $results->{$label}->{$aggregation}, + perf_label => $label . '_' . $aggregation, + }; + } + } + + $self->{output}->output_add(long_msg => sprintf("Command line: %s", $command_line), debug => 1); + $self->{output}->output_add(long_msg => sprintf("Raw data:\n%s", Dumper($raw_results)), debug => 1); +} + +1; + +__END__ + +=head1 MODE + +Check Azure metrics. + +Examples: +perl centreon_plugins.pl --plugin=cloud::azure::monitor::plugin --custommode=azcli --mode=get-metrics +--resource=MYSQLINSTANCE --resource-group=MYHOSTGROUP --resource-namespace='Microsoft.Compute' --resource-type='virtualMachines' +--metric='Percentage CPU' --aggregation=average –-interval=PT1M --timeframe=600 --warning-metric= --critical-metric= + +perl centreon_plugins.pl --plugin=cloud::azure::monitor::plugin --custommode=azcli --mode=get-metrics +--resource='/subscriptions/d29fe431/resourceGroups/MYHOSTGROUP/providers/Microsoft.Compute/virtualMachines/MYSQLINSTANCE' +--metric='Percentage CPU' --aggregation=average –-interval=PT1M --timeframe=600 --warning-metric= --critical-metric= + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-namespace> + +Set resource namespace (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used). + +=item B<--metric> + +Set monitor metrics (Required). + +=item B<--warning-metric> + +Threshold warning. + +=item B<--critical-metric> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/monitor/plugin.pm b/centreon-plugins/cloud/azure/monitor/plugin.pm new file mode 100644 index 000000000..492485dac --- /dev/null +++ b/centreon-plugins/cloud/azure/monitor/plugin.pm @@ -0,0 +1,50 @@ +# +# Copyright 2018 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::azure::monitor::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} = '1.0'; + %{$self->{modes}} = ( + 'get-metrics' => 'cloud::azure::monitor::mode::getmetrics', + ); + + $self->{custom_modes}{azcli} = 'cloud::azure::custom::azcli'; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Azure using API. + +=cut diff --git a/centreon-plugins/cloud/azure/network/mode/listresources.pm b/centreon-plugins/cloud/azure/network/mode/listresources.pm new file mode 100644 index 000000000..94d494ef5 --- /dev/null +++ b/centreon-plugins/cloud/azure/network/mode/listresources.pm @@ -0,0 +1,129 @@ +# +# Copyright 2018 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::azure::network::mode::listresources; + +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; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type', default => 'networkInterfaces' }, + "location:s" => { name => 'location' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{resources} = $options{custom}->azure_list_resources( + namespace => 'Microsoft.Network', + resource_type => $self->{option_results}->{resource_type}, + location => $self->{option_results}->{location}, + resource_group => $self->{option_results}->{resource_group} + ); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $resource (@{$self->{resources}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $resource->{name} !~ /$self->{option_results}->{filter_name}/); + $resource->{type} =~ s/Microsoft.Network\///g; + $self->{output}->output_add(long_msg => sprintf("[name = %s][resourcegroup = %s][location = %s][id = %s][type = %s]", + $resource->{name}, $resource->{resourceGroup}, $resource->{location}, $resource->{id}, $resource->{type})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List resources:'); + $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 => ['name', 'resourcegroup', 'location', 'id', 'type']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $resource (@{$self->{resources}}) { + $resource->{type} =~ s/Microsoft.Network\///g; + $self->{output}->add_disco_entry( + name => $resource->{name}, + resourcegroup => $resource->{resourceGroup}, + location => $resource->{location}, + id => $resource->{id}, + type => $resource->{type}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List network resources. + +=over 8 + +=item B<--resource-group> + +Set resource group. + +=item B<--resource-type> + +Set resource type (Default: 'networkInterfaces'). + +=item B<--location> + +Set resource location. + +=item B<--filter-name> + +Filter resource name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/network/mode/traffic.pm b/centreon-plugins/cloud/azure/network/mode/traffic.pm new file mode 100644 index 000000000..7e757d8e9 --- /dev/null +++ b/centreon-plugins/cloud/azure/network/mode/traffic.pm @@ -0,0 +1,324 @@ +# +# Copyright 2018 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::azure::network::mode::traffic; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; + $self->{result_values}->{metric_perf} = lc($options{extra_options}->{metric_perf}); + $self->{result_values}->{metric_label} = lc($options{extra_options}->{metric_label}); + $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; + $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric_perf} . '_' . $self->{result_values}->{stat}}; + $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_traffic_output { + my ($self, %options) = @_; + my $msg = ""; + + if (defined($instance_mode->{option_results}->{per_sec})) { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; + } else { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit; + } + return $msg; +} + +sub custom_packets_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($instance_mode->{option_results}->{per_sec}) ? 'packets/s' : 'packets', + value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_packets_output { + my ($self, %options) = @_; + my $msg =""; + + if (defined($instance_mode->{option_results}->{per_sec})) { + $msg = sprintf("%s: %.2f packets/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value_per_sec}); + } else { + $msg = sprintf("%s: %.2f packets", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); + } + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All network metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('BytesReceivedRate', 'BytesSentRate') { + my $metric_perf = lc($metric); + my $metric_label = lc($metric); + $metric_perf =~ s/ /_/g; + $metric_label =~ s/ /-/g; + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_perf . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric }, + closure_custom_output => $self->can('custom_traffic_output'), + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + foreach my $metric ('PacketsSentRate', 'PacketsReceivedRate') { + my $metric_perf = lc($metric); + my $metric_label = lc($metric); + $metric_perf =~ s/ /_/g; + $metric_label =~ s/ /-/g; + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_perf . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric }, + closure_custom_output => $self->can('custom_packets_output'), + closure_custom_perfdata => $self->can('custom_packets_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Compute'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Network\/.*\/.*$/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT5M"; + + $self->{az_aggregations} = ['Total']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('BytesReceivedRate', 'BytesSentRate', 'PacketsSentRate', 'PacketsReceivedRate') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{az_metrics}}, $metric; + } + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + $resource_name = $1 if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Network\/.*\/(.*)$/); + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{timeframe} = $self->{az_timeframe}; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check network resources traffic metrics. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::network::plugin --custommode=azcli --mode=traffic +--resource=MYSQLINSTANCE --resource-group=MYHOSTGROUP --resource-type=networkInterfaces +--aggregation='total' --critical-bytesreceivedrate-total='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::network::plugin --custommode=azcli --mode=traffic +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Network/networkInterfaces/xxx' +--aggregation='total' --critical-bytesreceivedrate-total='10' --verbose + +Default aggregation: 'total' / All aggregations are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'networkInterfaces'). + +=item B<--filter-metric> + +Filter metrics (Can be: 'BytesReceivedRate', 'BytesSentRate', +'PacketsSentRate', 'PacketsReceivedRate') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'bytesreceivedrate', 'bytessentrate', 'packetssentrate', +'packetsreceivedrate', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'bytesreceivedrate', 'bytessentrate', 'packetssentrate', +'packetsreceivedrate', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--per-sec> + +Change the data to be unit/sec. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/network/plugin.pm b/centreon-plugins/cloud/azure/network/plugin.pm new file mode 100644 index 000000000..212cd5682 --- /dev/null +++ b/centreon-plugins/cloud/azure/network/plugin.pm @@ -0,0 +1,50 @@ +# +# Copyright 2018 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::azure::network::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} } = ( + 'list-resources' => 'cloud::azure::network::mode::listresources', + 'throughput' => 'cloud::azure::network::mode::traffic', + ); + + $self->{custom_modes}{azcli} = 'cloud::azure::custom::azcli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Azure network provider. + +=cut diff --git a/centreon-plugins/cloud/azure/resources/mode/deploymentsstatus.pm b/centreon-plugins/cloud/azure/resources/mode/deploymentsstatus.pm new file mode 100644 index 000000000..7f3473d66 --- /dev/null +++ b/centreon-plugins/cloud/azure/resources/mode/deploymentsstatus.pm @@ -0,0 +1,237 @@ +# +# Copyright 2018 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::azure::resources::mode::deploymentsstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('status: %s [duration: %s] [last modified: %s]', $self->{result_values}->{status}, + $self->{result_values}->{duration}, + $self->{result_values}->{last_modified}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{duration} = $options{new_datas}->{$self->{instance} . '_duration'}; + $self->{result_values}->{last_modified} = $options{new_datas}->{$self->{instance} . '_last_modified'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Deployments "; +} + +sub prefix_deployment_output { + my ($self, %options) = @_; + + return "Deployment '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'deployments', type => 1, cb_prefix_output => 'prefix_deployment_output', message_multiple => 'All deployments are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-succeeded', set => { + key_values => [ { name => 'succeeded' } ], + output_template => "succeeded : %s", + perfdatas => [ + { label => 'total_succeeded', value => 'succeeded_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-failed', set => { + key_values => [ { name => 'failed' } ], + output_template => "failed : %s", + perfdatas => [ + { label => 'total_failed', value => 'failed_absolute', template => '%d', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{deployments} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'duration' }, { name => 'last_modified' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} ne "Succeeded"' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource_group}) || $self->{option_results}->{resource_group} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --resource-group option"); + $self->{output}->option_exit(); + } + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { + succeeded => 0, failed => 0, + }; + $self->{deployments} = {}; + my $deployments = $options{custom}->azure_list_deployments(resource_group => $self->{option_results}->{resource_group}); + foreach my $deployment (@{$deployments}) { + $self->{deployments}->{$deployment->{id}} = { + display => $deployment->{name}, + status => $deployment->{properties}->{provisioningState}, + duration => $deployment->{properties}->{duration}, + last_modified => $deployment->{properties}->{timestamp}, + }; + + foreach my $status (keys %{$self->{global}}) { + $self->{global}->{$status}++ if ($deployment->{properties}->{provisioningState} =~ /$status/i); + } + } + + if (scalar(keys %{$self->{deployments}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No virtual machines found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check deployments status. + +Example: +perl centreon_plugins.pl --plugin=cloud::azure::compute::plugin --custommode=azcli --mode=deployments-status +--filter-counters='^total-failed$' --critical-total-failed='1' --verbose + +=over 8 + +=item B<--resource-group> + +Set resource group (Requied). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-succeeded$' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} ne "Succeeded"'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-succeeded', 'total-failed'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-succeeded', 'total-failed'. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/resources/mode/items.pm b/centreon-plugins/cloud/azure/resources/mode/items.pm new file mode 100644 index 000000000..f5c257f79 --- /dev/null +++ b/centreon-plugins/cloud/azure/resources/mode/items.pm @@ -0,0 +1,184 @@ +# +# Copyright 2018 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::azure::resources::mode::items; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_group_output { + my ($self, %options) = @_; + + return "Resource group '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'groups', type => 1, cb_prefix_output => 'prefix_group_output', message_multiple => 'All groups are ok' }, + ]; + + $self->{maps_counters}->{groups} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } , { name => 'display' } ], + output_template => "Total number of items : %s", + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%d', + label_extra_instance => 1, instance_use => 'display_absolute', min => 0 }, + ], + } + }, + { label => 'compute', set => { + key_values => [ { name => 'compute' } , { name => 'display' } ], + output_template => "Compute: %s", + perfdatas => [ + { label => 'compute', value => 'compute_absolute', template => '%d', + label_extra_instance => 1, instance_use => 'display_absolute', min => 0 }, + ], + } + }, + { label => 'storage', set => { + key_values => [ { name => 'storage' } , { name => 'display' } ], + output_template => "Storage: %s", + perfdatas => [ + { label => 'storage', value => 'storage_absolute', template => '%d', + label_extra_instance => 1, instance_use => 'display_absolute', min => 0 }, + ], + } + }, + { label => 'network', set => { + key_values => [ { name => 'network' } , { name => 'display' } ], + output_template => "Network: %s", + perfdatas => [ + { label => 'network', value => 'network_absolute', template => '%d', + label_extra_instance => 1, instance_use => 'display_absolute', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "filter-name:s" => { name => 'filter_name' }, + "hidden" => { name => 'hidden' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $resources = $options{custom}->azure_list_resources( + namespace => '', + resource_type => '', + location => $self->{option_results}->{location}, + resource_group => $self->{option_results}->{resource_group} + ); + + my $groups; + if (defined($self->{option_results}->{resource_group}) && $self->{option_results}->{resource_group} ne '') { + push @{$groups}, { name => $self->{option_results}->{resource_group} }; + } else { + $groups = $options{custom}->azure_list_groups(); + } + + foreach my $group (@{$groups}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $group->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $group->{name} . "': no matching filter.", debug => 1); + next; + } + + $self->{groups}->{$group->{name}} = { + display => $group->{name}, + total => 0, + compute => 0, + storage => 0, + network => 0, + }; + + foreach my $item (@{$resources}) { + next if ($item->{resourceGroup} !~ /$group->{name}/); + next if (!defined($self->{option_results}->{hidden}) && $item->{type} =~ /^Microsoft\..*\/.*\/.*/); + $self->{groups}->{$group->{name}}->{total}++; + $self->{groups}->{$group->{name}}->{compute}++ if ($item->{type} =~ /^Microsoft\.Compute\//); + $self->{groups}->{$group->{name}}->{storage}++ if ($item->{type} =~ /^Microsoft\.Storage\//); + $self->{groups}->{$group->{name}}->{network}++ if ($item->{type} =~ /^Microsoft\.Network\//); + } + } + + if (scalar(keys %{$self->{groups}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No groups found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check number of items in resource groups. + +Example: +perl centreon_plugins.pl --plugin=cloud::azure::resources::plugin --custommode=azcli --mode=items +--filter-name='.*' --critical-items='10' --verbose + +=over 8 + +=item B<--resource-group> + +Set resource group (Optional). + +=item B<--filter-name> + +Filter resource name (Can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'items'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'items'. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/resources/mode/listgroups.pm b/centreon-plugins/cloud/azure/resources/mode/listgroups.pm new file mode 100644 index 000000000..80b4aa3ae --- /dev/null +++ b/centreon-plugins/cloud/azure/resources/mode/listgroups.pm @@ -0,0 +1,112 @@ +# +# Copyright 2018 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::azure::resources::mode::listgroups; + +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; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "location:s" => { name => 'location' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{groups} = $options{custom}->azure_list_groups(); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $group (@{$self->{groups}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $group->{name} !~ /$self->{option_results}->{filter_name}/); + next if (defined($self->{option_results}->{location}) && $self->{option_results}->{location} ne '' + && $group->{location} !~ /$self->{option_results}->{location}/); + $self->{output}->output_add(long_msg => sprintf("[name = %s][location = %s][id = %s]", + $group->{name}, $group->{location}, $group->{id})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List groups:'); + $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 => ['name', 'location', 'id']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $group (@{$self->{groups}}) { + $self->{output}->add_disco_entry( + name => $group->{name}, + location => $group->{location}, + id => $group->{id}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List resources groups. + +=over 8 + +=item B<--location> + +Set group location (Can be a regexp). + +=item B<--filter-name> + +Filter group name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/resources/mode/listresources.pm b/centreon-plugins/cloud/azure/resources/mode/listresources.pm new file mode 100644 index 000000000..d2a2b327f --- /dev/null +++ b/centreon-plugins/cloud/azure/resources/mode/listresources.pm @@ -0,0 +1,129 @@ +# +# Copyright 2018 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::azure::resources::mode::listresources; + +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; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "location:s" => { name => 'location' }, + "filter-type:s" => { name => 'filter_type' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{resources} = $options{custom}->azure_list_resources( + namespace => '', + resource_type => '', + location => $self->{option_results}->{location}, + resource_group => $self->{option_results}->{resource_group} + ); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $resource (@{$self->{resources}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $resource->{name} !~ /$self->{option_results}->{filter_name}/); + next if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' + && $resource->{type} !~ /$self->{option_results}->{filter_type}/); + $self->{output}->output_add(long_msg => sprintf("[name = %s][resourcegroup = %s][location = %s][id = %s][type = %s]", + $resource->{name}, $resource->{resourceGroup}, $resource->{location}, $resource->{id}, $resource->{type})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List resources:'); + $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 => ['name', 'resourcegroup', 'location', 'id', 'type']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $resource (@{$self->{resources}}) { + $self->{output}->add_disco_entry( + name => $resource->{name}, + resourcegroup => $resource->{resourceGroup}, + location => $resource->{location}, + id => $resource->{id}, + type => $resource->{type}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List resources. + +=over 8 + +=item B<--resource-group> + +Set resource group. + +=item B<--location> + +Set resource location. + +=item B<--filter-type> + +Filter resource type (Can be a regexp). + +=item B<--filter-name> + +Filter resource name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/resources/plugin.pm b/centreon-plugins/cloud/azure/resources/plugin.pm new file mode 100644 index 000000000..ac5271b21 --- /dev/null +++ b/centreon-plugins/cloud/azure/resources/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2018 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::azure::resources::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} } = ( + 'deployments-status' => 'cloud::azure::resources::mode::deploymentsstatus', + 'list-groups' => 'cloud::azure::resources::mode::listgroups', + 'list-resources' => 'cloud::azure::resources::mode::listresources', + 'items' => 'cloud::azure::resources::mode::items', + ); + + $self->{custom_modes}{azcli} = 'cloud::azure::custom::azcli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Azure resources provider. + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/accountusedcapacity.pm b/centreon-plugins/cloud/azure/storage/mode/accountusedcapacity.pm new file mode 100644 index 000000000..a64b037ad --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/accountusedcapacity.pm @@ -0,0 +1,205 @@ +# +# Copyright 2018 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::azure::storage::mode::accountusedcapacity; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All capacity metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('total') { + foreach my $metric ('UsedCapacity') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Total']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('UsedCapacity') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)$/) { + $resource_name = $1; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources used capacity metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=account-used-capacity +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='total' --critical-usedcapacity-total='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=account-used-capacity +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx' +--aggregation='total' --critical-usedcapacity-total='10' --verbose + +Default aggregation: 'total' / Only total is valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-usedcapacity-total> + +Thresholds warning + +=item B<--critical-usedcapacity-total> + +Thresholds critical + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/blobcapacity.pm b/centreon-plugins/cloud/azure/storage/mode/blobcapacity.pm new file mode 100644 index 000000000..ef50b2cab --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/blobcapacity.pm @@ -0,0 +1,207 @@ +# +# Copyright 2018 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::azure::storage::mode::blobcapacity; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All capacity metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('total') { + foreach my $metric ('BlobCapacity') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Total']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('BlobCapacity') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/blobServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources blob capacity metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=blob-capacity +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='total' --critical-blobcapacity-total='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=blob-capacity +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/blobServices/default' +--aggregation='total' --critical-blobcapacity-total='10' --verbose + +Default aggregation: 'total' / Only total is valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-blobcapacity-total> + +Thresholds warning + +=item B<--critical-blobcapacity-total> + +Thresholds critical + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/blobcontainercount.pm b/centreon-plugins/cloud/azure/storage/mode/blobcontainercount.pm new file mode 100644 index 000000000..26bf09031 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/blobcontainercount.pm @@ -0,0 +1,206 @@ +# +# Copyright 2018 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::azure::storage::mode::blobcontainercount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All count metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('ContainerCount') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('ContainerCount') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/blobServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources blob container count metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=blob-container-count +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-containercount-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=blob-container-count + --resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/blobServices/default' +--aggregation='average' --critical-containercount-average='10' --verbose + +Default aggregation: 'average' / Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-containercount-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-containercount-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/blobcount.pm b/centreon-plugins/cloud/azure/storage/mode/blobcount.pm new file mode 100644 index 000000000..3a3e0def0 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/blobcount.pm @@ -0,0 +1,206 @@ +# +# Copyright 2018 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::azure::storage::mode::blobcount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All count metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('total') { + foreach my $metric ('BlobCount') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Total']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('BlobCount') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/blobServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources blob capacity metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=blob-capacity +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='total' --critical-blobcapacity-total='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=blob-capacity +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/blobServices/default' +--aggregation='total' --critical-blobcapacity-total='10' --verbose + +Default aggregation: 'total' / Only total is valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-blobcapacity-total> + +Thresholds warning + +=item B<--critical-blobcapacity-total> + +Thresholds critical + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/filecapacity.pm b/centreon-plugins/cloud/azure/storage/mode/filecapacity.pm new file mode 100644 index 000000000..b9097798a --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/filecapacity.pm @@ -0,0 +1,207 @@ +# +# Copyright 2018 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::azure::storage::mode::filecapacity; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All capacity metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('FileCapacity') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('FileCapacity') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/fileServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources file capacity metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=file-capacity +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-filecapacity-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=file-capacity +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/fileServices/default' +--aggregation='average' --critical-filecapacity-average='10' --verbose + +Default aggregation: 'average' /Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-filecapacity-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-filecapacity-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/filecount.pm b/centreon-plugins/cloud/azure/storage/mode/filecount.pm new file mode 100644 index 000000000..3794ef9d6 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/filecount.pm @@ -0,0 +1,206 @@ +# +# Copyright 2018 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::azure::storage::mode::filecount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All count metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('FileCount') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('FileCount') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/fileServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources file count metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=file-count +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-filecount-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=file-count +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/fileServices/default' +--aggregation='average' --critical-filecount-average='10' --verbose + +Default aggregation: 'average' / Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-filecount-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-filecount-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/filesharecount.pm b/centreon-plugins/cloud/azure/storage/mode/filesharecount.pm new file mode 100644 index 000000000..89cf7aeaf --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/filesharecount.pm @@ -0,0 +1,206 @@ +# +# Copyright 2018 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::azure::storage::mode::filesharecount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All count metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('FileShareCount') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('FileShareCount') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/fileServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources file share count metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=file-share-count +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-filesharecount-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=file-share-count +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/fileServices/default' +--aggregation='average' --critical-filesharecount-average='10' --verbose + +Default aggregation: 'average' / Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-filesharecount-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-filesharecount-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/listresources.pm b/centreon-plugins/cloud/azure/storage/mode/listresources.pm new file mode 100644 index 000000000..0e1b08a1b --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/listresources.pm @@ -0,0 +1,129 @@ +# +# Copyright 2018 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::azure::storage::mode::listresources; + +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; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type', default => 'storageAccounts' }, + "location:s" => { name => 'location' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{resources} = $options{custom}->azure_list_resources( + namespace => 'Microsoft.Storage', + resource_type => $self->{option_results}->{resource_type}, + location => $self->{option_results}->{location}, + resource_group => $self->{option_results}->{resource_group} + ); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $resource (@{$self->{resources}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $resource->{name} !~ /$self->{option_results}->{filter_name}/); + $resource->{type} =~ s/Microsoft.Storage\///g; + $self->{output}->output_add(long_msg => sprintf("[name = %s][resourcegroup = %s][location = %s][id = %s][type = %s]", + $resource->{name}, $resource->{resourceGroup}, $resource->{location}, $resource->{id}, $resource->{type})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List resources:'); + $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 => ['name', 'resourcegroup', 'location', 'id', 'type']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $resource (@{$self->{resources}}) { + $resource->{type} =~ s/Microsoft.Storage\///g; + $self->{output}->add_disco_entry( + name => $resource->{name}, + resourcegroup => $resource->{resourceGroup}, + location => $resource->{location}, + id => $resource->{id}, + type => $resource->{type}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List storage resources. + +=over 8 + +=item B<--resource-group> + +Set resource group. + +=item B<--resource-type> + +Set resource type (Default: 'storageAccounts'). + +=item B<--location> + +Set resource location. + +=item B<--filter-name> + +Filter resource name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/queuecapacity.pm b/centreon-plugins/cloud/azure/storage/mode/queuecapacity.pm new file mode 100644 index 000000000..8c020082a --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/queuecapacity.pm @@ -0,0 +1,207 @@ +# +# Copyright 2018 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::azure::storage::mode::queuecapacity; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All capacity metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('QueueCapacity') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('QueueCapacity') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/queueServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources queue capacity metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=queue-capacity +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-queuecapacity-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=queue-capacity +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/queueServices/default' +--aggregation='average' --critical-queuecapacity-average='10' --verbose + +Default aggregation: 'average' /Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-queuecapacity-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-queuecapacity-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/queuecount.pm b/centreon-plugins/cloud/azure/storage/mode/queuecount.pm new file mode 100644 index 000000000..90ecfeb4f --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/queuecount.pm @@ -0,0 +1,206 @@ +# +# Copyright 2018 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::azure::storage::mode::queuecount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All count metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('QueueCount') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('QueueCount') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/queueServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources queue count metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=queue-count +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-queuecount-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=queue-count +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/queueServices/default' +--aggregation='average' --critical-queuecount-average='10' --verbose + +Default aggregation: 'average' / Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-queuecount-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-queuecount-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/queuemessagecount.pm b/centreon-plugins/cloud/azure/storage/mode/queuemessagecount.pm new file mode 100644 index 000000000..6bfb90982 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/queuemessagecount.pm @@ -0,0 +1,206 @@ +# +# Copyright 2018 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::azure::storage::mode::queuemessagecount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All count metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('QueueMessageCount') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('QueueMessageCount') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/queueServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources queue message count metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=queue-message-count +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-queuemessagecount-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=queue-message-count +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/queueServices/default' +--aggregation='average' --critical-queuemessagecount-average='10' --verbose + +Default aggregation: 'average' / Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-queuemessagecount-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-queuemessagecount-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/tablecapacity.pm b/centreon-plugins/cloud/azure/storage/mode/tablecapacity.pm new file mode 100644 index 000000000..3628090fa --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/tablecapacity.pm @@ -0,0 +1,207 @@ +# +# Copyright 2018 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::azure::storage::mode::tablecapacity; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All capacity metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('TableCapacity') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('TableCapacity') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/tableServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources table capacity metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=table-capacity +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-tablecapacity-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=table-capacity +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/tableServices/default' +--aggregation='average' --critical-tablecapacity-average='10' --verbose + +Default aggregation: 'average' /Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-tablecapacity-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-tablecapacity-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/tablecount.pm b/centreon-plugins/cloud/azure/storage/mode/tablecount.pm new file mode 100644 index 000000000..16e6f42bc --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/tablecount.pm @@ -0,0 +1,206 @@ +# +# Copyright 2018 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::azure::storage::mode::tablecount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All count metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('TableCount') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('TableCount') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/tableServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources table count metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=table-count +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-tablecount-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=table-count +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/tableServices/default' +--aggregation='average' --critical-tablecount-average='10' --verbose + +Default aggregation: 'average' / Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-tablecount-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-tablecount-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/tableentitycount.pm b/centreon-plugins/cloud/azure/storage/mode/tableentitycount.pm new file mode 100644 index 000000000..e064951a8 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/tableentitycount.pm @@ -0,0 +1,206 @@ +# +# Copyright 2018 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::azure::storage::mode::tableentitycount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Resource '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All count metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('average', 'total') { + foreach my $metric ('TableEntityCount') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %s', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%s', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 3600; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT1H"; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('TableEntityCount') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = '/tableServices/default'; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/.*\/default$/) { + $resource_name = $1; + $namespace_full = ''; + } + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources table entity count metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=table-entity-count +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts +--aggregation='average' --critical-tableentitycount-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=table-entity-count +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx/tableServices/default' +--aggregation='average' --critical-tableentitycount-average='10' --verbose + +Default aggregation: 'average' / Total and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--warning-tableentitycount-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'average', 'total'). + +=item B<--critical-tableentitycount-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/transactionsavailability.pm b/centreon-plugins/cloud/azure/storage/mode/transactionsavailability.pm new file mode 100644 index 000000000..339f81cd2 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/transactionsavailability.pm @@ -0,0 +1,222 @@ +# +# Copyright 2018 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::azure::storage::mode::transactionsavailability; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub prefix_metric_output { + my ($self, %options) = @_; + + my $msg = "Resource '" . $options{instance_value}->{display} . "'"; + $msg .= " (" . $options{instance_value}->{namespace} . ")" if ($options{instance_value}->{namespace} ne ''); + $msg .= " " . $options{instance_value}->{stat} . " "; + + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All transactions metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average') { + foreach my $metric ('Availability') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %.2f', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%.2f', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "resource-namespace:s" => { name => 'resource_namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*$/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT5M"; + $self->{az_resource_extra_namespace} = defined($self->{option_results}->{resource_namespace}) ? $self->{option_results}->{resource_namespace} : ''; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('Availability') { + push @{$self->{az_metrics}}, $metric; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = ($self->{az_resource_extra_namespace} ne '') ? '/' . lc($self->{az_resource_extra_namespace}) . 'Services/default' : ''; + my $namespace_name = ($self->{az_resource_extra_namespace} ne '') ? $self->{az_resource_extra_namespace} : "Account"; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/(.*)\/default$/ || + $resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)$/) { + $resource_name = $1; + $namespace_name = $2 if(defined($2)); + } + $namespace_name =~ s/Services//g; + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{timeframe} = $self->{az_timeframe}; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{namespace} = ucfirst($namespace_name); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources transaction availability metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=transactions-availability +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts --resource-namespace=Blob +--aggregation='average' --critical-availability-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=transactions-availability +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx' +--aggregation='average' --critical-availability-average='10' --verbose + +Default aggregation: 'average' / Minimum, maximum and average are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--resource-namespace> + +Set resource namespace (Can be: 'Blob', 'File', 'Table', 'Queue'). +Leave empty for account metric. + +=item B<--warning-availability-$aggregation$> + +Thresholds warning ($aggregation$ can be: 'minimum', 'maximum', 'average'). + +=item B<--critical-availability-$aggregation$> + +Thresholds critical ($aggregation$ can be: 'minimum', 'maximum', 'average'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/transactionscount.pm b/centreon-plugins/cloud/azure/storage/mode/transactionscount.pm new file mode 100644 index 000000000..b683a7a36 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/transactionscount.pm @@ -0,0 +1,283 @@ +# +# Copyright 2018 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::azure::storage::mode::transactionscount; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub prefix_metric_output { + my ($self, %options) = @_; + + my $msg = "Resource '" . $options{instance_value}->{display} . "'"; + $msg .= " (" . $options{instance_value}->{namespace} . ")" if ($options{instance_value}->{namespace} ne ''); + $msg .= " " . $options{instance_value}->{stat} . " "; + + return $msg; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; + $self->{result_values}->{metric_perf} = lc($options{extra_options}->{metric_perf}); + $self->{result_values}->{metric_label} = lc($options{extra_options}->{metric_label}); + $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; + $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric_perf} . '_' . $self->{result_values}->{stat}}; + $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{namespace} = $options{new_datas}->{$self->{instance} . '_namespace'}; + return 0; +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($instance_mode->{option_results}->{per_sec}) ? 'transactions/s' : 'transactions', + value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_usage_output { + my ($self, %options) = @_; + my $msg = ""; + + if (defined($instance_mode->{option_results}->{per_sec})) { + $msg = sprintf("%s: %.2f transactions/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value_per_sec}); + } else { + $msg = sprintf("%s: %.2f transactions", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); + } + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All transactions metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('total') { + foreach my $metric ('Transactions') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' }, { name => 'namespace' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_label, + metric_label => $metric_label, metric_name => $metric }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "resource-namespace:s" => { name => 'resource_namespace' }, + "per-sec" => { name => 'per_sec' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT5M"; + $self->{az_resource_extra_namespace} = defined($self->{option_results}->{resource_namespace}) ? $self->{option_results}->{resource_namespace} : ''; + + $self->{az_aggregations} = ['Total']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('Transactions') { + push @{$self->{az_metrics}}, $metric; + } + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = ($self->{az_resource_extra_namespace} ne '') ? '/' . lc($self->{az_resource_extra_namespace}) . 'Services/default' : ''; + my $namespace_name = ($self->{az_resource_extra_namespace} ne '') ? $self->{az_resource_extra_namespace} : "Account"; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/(.*)\/default$/ || + $resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)$/) { + $resource_name = $1; + $namespace_name = $2 if(defined($2)); + } + $namespace_name =~ s/Services//g; + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{timeframe} = $self->{az_timeframe}; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{namespace} = ucfirst($namespace_name); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources transaction count metric. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=transactions-count +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts --resource-namespace=Blob +--aggregation='total' --critical-transactions-total='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=transactions-count +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx' +--aggregation='total' --critical-transactions-total='10' --verbose + +Default aggregation: 'total' / Only total is valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--resource-namespace> + +Set resource namespace (Can be: 'Blob', 'File', 'Table', 'Queue'). +Leave empty for account metric. + +=item B<--warning-transactions-total> + +Thresholds warning. + +=item B<--critical-transactions-total> + +Thresholds critical. + +=item B<--per-sec> + +Change the data to be unit/sec. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/transactionslatency.pm b/centreon-plugins/cloud/azure/storage/mode/transactionslatency.pm new file mode 100644 index 000000000..acee8eb25 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/transactionslatency.pm @@ -0,0 +1,236 @@ +# +# Copyright 2018 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::azure::storage::mode::transactionslatency; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub prefix_metric_output { + my ($self, %options) = @_; + + my $msg = "Resource '" . $options{instance_value}->{display} . "'"; + $msg .= " (" . $options{instance_value}->{namespace} . ")" if ($options{instance_value}->{namespace} ne ''); + $msg .= " " . $options{instance_value}->{stat} . " "; + + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All transactions metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('SuccessServerLatency', 'SuccessE2ELatency') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric . ': %.2f ms', + perfdatas => [ + { label => $metric_label . '_' . $aggregation, value => $metric_label . '_' . $aggregation . '_absolute', + template => '%.2f', unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "resource-namespace:s" => { name => 'resource_namespace' }, + "filter-metric:s" => { name => 'filter_metric' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT5M"; + $self->{az_resource_extra_namespace} = defined($self->{option_results}->{resource_namespace}) ? $self->{option_results}->{resource_namespace} : ''; + + $self->{az_aggregations} = ['Average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('SuccessServerLatency', 'SuccessE2ELatency') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{az_metrics}}, $metric; + } + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = ($self->{az_resource_extra_namespace} ne '') ? '/' . lc($self->{az_resource_extra_namespace}) . 'Services/default' : ''; + my $namespace_name = ($self->{az_resource_extra_namespace} ne '') ? $self->{az_resource_extra_namespace} : "Account"; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/(.*)\/default$/ || + $resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)$/) { + $resource_name = $1; + $namespace_name = $2 if(defined($2)); + } + $namespace_name =~ s/Services//g; + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{timeframe} = $self->{az_timeframe}; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{namespace} = ucfirst($namespace_name); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources transaction latency metrics. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=transactions-latency +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts --resource-namespace=Blob +--aggregation='average' --critical-successserverlatency-average='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=transactions-latency +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx' +--aggregation='average' --critical-successserverlatency-average='10' --verbose + +Default aggregation: 'average' / All aggregations are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--resource-namespace> + +Set resource namespace (Can be: 'Blob', 'File', 'Table', 'Queue'). +Leave empty for account metric. + +=item B<--filter-metric> + +Filter metrics (Can be: 'SuccessServerLatency', 'SuccessE2ELatency') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'successserverlatency', 'successe2elatency', +$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'successserverlatency', 'successe2elatency', +$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/mode/transactionsthroughput.pm b/centreon-plugins/cloud/azure/storage/mode/transactionsthroughput.pm new file mode 100644 index 000000000..f70d3203a --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/mode/transactionsthroughput.pm @@ -0,0 +1,295 @@ +# +# Copyright 2018 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::azure::storage::mode::transactionsthroughput; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub prefix_metric_output { + my ($self, %options) = @_; + + my $msg = "Resource '" . $options{instance_value}->{display} . "'"; + $msg .= " (" . $options{instance_value}->{namespace} . ")" if ($options{instance_value}->{namespace} ne ''); + $msg .= " " . $options{instance_value}->{stat} . " "; + + return $msg; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; + $self->{result_values}->{metric_perf} = lc($options{extra_options}->{metric_perf}); + $self->{result_values}->{metric_label} = lc($options{extra_options}->{metric_label}); + $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; + $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric_perf} . '_' . $self->{result_values}->{stat}}; + $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{namespace} = $options{new_datas}->{$self->{instance} . '_namespace'}; + return 0; +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_usage_output { + my ($self, %options) = @_; + my $msg = ""; + + if (defined($instance_mode->{option_results}->{per_sec})) { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; + } else { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit; + } + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All transactions metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('Ingress', 'Egress') { + my $metric_label = lc($metric); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric_label . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' }, { name => 'namespace' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_label, + metric_label => $metric_label, metric_name => $metric }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-type:s" => { name => 'resource_type' }, + "resource-namespace:s" => { name => 'resource_namespace' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{resource})) { + $self->{output}->add_option_msg(short_msg => "Need to specify either --resource with --resource-group and --resource-type options or --resource ."); + $self->{output}->option_exit(); + } + + $self->{az_resource_group} = ''; + $self->{az_resource_type} = ''; + $self->{az_resource_namespace} = 'Microsoft.Storage'; + + foreach my $resource (@{$self->{option_results}->{resource}}) { + push @{$self->{az_resource}}, $resource; + if ($resource =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/.*/) { + $self->{az_resource_namespace} = ''; + } else { + $self->{az_resource_group} = $self->{option_results}->{resource_group}; + $self->{az_resource_type} = $self->{option_results}->{resource_type}; + } + } + + $self->{az_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{az_interval} = defined($self->{option_results}->{interval}) ? $self->{option_results}->{interval} : "PT5M"; + $self->{az_resource_extra_namespace} = defined($self->{option_results}->{resource_namespace}) ? $self->{option_results}->{resource_namespace} : ''; + + $self->{az_aggregations} = ['Total']; + if (defined($self->{option_results}->{aggregation})) { + $self->{az_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{az_aggregations}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric ('Ingress', 'Egress') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{az_metrics}}, $metric; + } + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %metric_results; + foreach my $resource (@{$self->{az_resource}}) { + my $resource_name = $resource; + my $namespace_full = ($self->{az_resource_extra_namespace} ne '') ? '/' . lc($self->{az_resource_extra_namespace}) . 'Services/default' : ''; + my $namespace_name = ($self->{az_resource_extra_namespace} ne '') ? $self->{az_resource_extra_namespace} : "Account"; + if ($resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)\/(.*)\/default$/ || + $resource_name =~ /^\/subscriptions\/.*\/resourceGroups\/.*\/providers\/Microsoft\.Storage\/.*\/(.*)$/) { + $resource_name = $1; + $namespace_name = $2 if(defined($2)); + } + $namespace_name =~ s/Services//g; + + ($metric_results{$resource_name}, undef, undef) = $options{custom}->azure_get_metrics( + resource => $resource . $namespace_full, + resource_group => $self->{az_resource_group}, + resource_type => $self->{az_resource_type}, + resource_namespace => $self->{az_resource_namespace}, + metrics => $self->{az_metrics}, + aggregations => $self->{az_aggregations}, + timeframe => $self->{az_timeframe}, + interval => $self->{az_interval}, + ); + + foreach my $metric (@{$self->{az_metrics}}) { + my $metric_name = lc($metric); + $metric_name =~ s/ /_/g; + foreach my $aggregation (@{$self->{az_aggregations}}) { + next if (!defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{display} = $resource_name; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{timeframe} = $self->{az_timeframe}; + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{namespace} = ucfirst($namespace_name); + $self->{metric}->{$resource_name . "_" . lc($aggregation)}->{$metric_name . "_" . lc($aggregation)} = defined($metric_results{$resource_name}->{$metric_name}->{lc($aggregation)}) ? $metric_results{$resource_name}->{$metric_name}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check storage resources transaction throughput metrics. + +Example: + +Using resource name : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=transactions-throughput +--resource=MYFILER --resource-group=MYHOSTGROUP --resource-type=storageAccounts --resource-namespace=Blob +--aggregation='total' --critical-egress-total='10' --verbose + +Using resource id : + +perl centreon_plugins.pl --plugin=cloud::azure::storage::plugin --custommode=azcli --mode=transactions-throughput +--resource='/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Storage/storageAccounts/xxx' +--aggregation='total' --critical-egress-total='10' --verbose + +Default aggregation: 'total' / All aggregations are valid. + +=over 8 + +=item B<--resource> + +Set resource name or id (Required). + +=item B<--resource-group> + +Set resource group (Required if resource's name is used). + +=item B<--resource-type> + +Set resource type (Required if resource's name is used) (Can be: 'storageAccounts'). + +=item B<--resource-namespace> + +Set resource namespace (Can be: 'Blob', 'File', 'Table', 'Queue'). +Leave empty for account metric. + +=item B<--filter-metric> + +Filter metrics (Can be: 'Ingress', 'Egress') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'ingress', 'egress', +$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'ingress', 'egress', +$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--per-sec> + +Change the data to be unit/sec. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/storage/plugin.pm b/centreon-plugins/cloud/azure/storage/plugin.pm new file mode 100644 index 000000000..92aadd291 --- /dev/null +++ b/centreon-plugins/cloud/azure/storage/plugin.pm @@ -0,0 +1,66 @@ +# +# Copyright 2018 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::azure::storage::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} } = ( + 'account-used-capacity' => 'cloud::azure::storage::mode::accountusedcapacity', + 'blob-capacity' => 'cloud::azure::storage::mode::blobcapacity', + 'blob-container-count' => 'cloud::azure::storage::mode::blobcontainercount', + 'blob-count' => 'cloud::azure::storage::mode::blobcount', + 'file-capacity' => 'cloud::azure::storage::mode::filecapacity', + 'file-count' => 'cloud::azure::storage::mode::filecount', + 'file-share-count' => 'cloud::azure::storage::mode::filesharecount', + 'list-resources' => 'cloud::azure::storage::mode::listresources', + 'queue-capacity' => 'cloud::azure::storage::mode::queuecapacity', + 'queue-count' => 'cloud::azure::storage::mode::queuecount', + 'queue-message-count' => 'cloud::azure::storage::mode::queuemessagecount', + 'table-capacity' => 'cloud::azure::storage::mode::tablecapacity', + 'table-count' => 'cloud::azure::storage::mode::tablecount', + 'table-entity-count' => 'cloud::azure::storage::mode::tableentitycount', + 'transactions-availability' => 'cloud::azure::storage::mode::transactionsavailability', + 'transactions-count' => 'cloud::azure::storage::mode::transactionscount', + 'transactions-latency' => 'cloud::azure::storage::mode::transactionslatency', + 'transactions-throughput' => 'cloud::azure::storage::mode::transactionsthroughput', + ); + + $self->{custom_modes}{azcli} = 'cloud::azure::custom::azcli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Azure storage provider. + +=cut