From 42da42aa56bb30345a72998f9c8d7dad6681c6f7 Mon Sep 17 00:00:00 2001 From: Colin Gagnaire Date: Thu, 24 Jan 2019 16:17:41 +0100 Subject: [PATCH] add azure recovery/backup service --- centreon-plugins/cloud/azure/custom/api.pm | 82 ++++++ centreon-plugins/cloud/azure/custom/azcli.pm | 143 +++++++++++ .../recovery/mode/backupitemsstatus.pm | 224 +++++++++++++++++ .../recovery/mode/backupjobsstatus.pm | 233 ++++++++++++++++++ .../recovery/mode/listbackupjobs.pm | 156 ++++++++++++ .../management/recovery/mode/listvaults.pm | 137 ++++++++++ .../cloud/azure/management/recovery/plugin.pm | 63 +++++ 7 files changed, 1038 insertions(+) create mode 100644 centreon-plugins/cloud/azure/management/recovery/mode/backupitemsstatus.pm create mode 100644 centreon-plugins/cloud/azure/management/recovery/mode/backupjobsstatus.pm create mode 100644 centreon-plugins/cloud/azure/management/recovery/mode/listbackupjobs.pm create mode 100644 centreon-plugins/cloud/azure/management/recovery/mode/listvaults.pm create mode 100644 centreon-plugins/cloud/azure/management/recovery/plugin.pm diff --git a/centreon-plugins/cloud/azure/custom/api.pm b/centreon-plugins/cloud/azure/custom/api.pm index ece8209da..997261c3d 100644 --- a/centreon-plugins/cloud/azure/custom/api.pm +++ b/centreon-plugins/cloud/azure/custom/api.pm @@ -239,6 +239,28 @@ sub request_api { return $decoded; } +sub convert_duration { + my ($self, %options) = @_; + + my $duration; + if ($options{time_string} =~ /^P.*S$/) { + centreon::plugins::misc::mymodule_load(module => 'DateTime::Format::Duration::ISO8601', + error_msg => "Cannot load module 'DateTime::Format::Duration::ISO8601'."); + + my $format = DateTime::Format::Duration::ISO8601->new; + my $d = $format->parse_duration($options{time_string}); + $duration = $d->minutes * 60 + $d->seconds; + } elsif ($options{time_string} =~ /^(\d+):(\d+):(\d+)\.\d+$/) { + centreon::plugins::misc::mymodule_load(module => 'DateTime::Duration', + error_msg => "Cannot load module 'DateTime::Format::Duration'."); + + my $d = DateTime::Duration->new(hours => $1, minutes => $2, seconds => $3); + $duration = $d->minutes * 60 + $d->seconds; + } + + return $duration; +} + sub azure_get_metrics_set_url { my ($self, %options) = @_; @@ -392,6 +414,66 @@ sub azure_list_deployments { return $response->{value}; } +sub azure_list_vaults_set_url { + my ($self, %options) = @_; + + my $url = $self->{management_endpoint} . "/subscriptions/" . $self->{subscription}; + $url .= "/resourceGroups/" . $options{resource_group} if (defined($options{resource_group}) && $options{resource_group} ne ''); + $url .= "/providers/Microsoft.RecoveryServices/vaults?api-version=" . $self->{api_version}; + + return $url; +} + +sub azure_list_vaults { + my ($self, %options) = @_; + + my $results = {}; + my $full_url = $self->azure_list_vaults_set_url(%options); + my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => ''); + + return $response->{value}; +} + +sub azure_list_backup_jobs_set_url { + my ($self, %options) = @_; + + my $url = $self->{management_endpoint} . "/subscriptions/" . $self->{subscription} . "/resourcegroups/" . + $options{resource_group} . "/providers/Microsoft.RecoveryServices/vaults/" . + $options{vault_name} . "/backupJobs?api-version=" . $self->{api_version}; + + return $url; +} + +sub azure_list_backup_jobs { + my ($self, %options) = @_; + + my $results = {}; + my $full_url = $self->azure_list_backup_jobs_set_url(%options); + my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => ''); + + return $response->{value}; +} + +sub azure_list_backup_items_set_url { + my ($self, %options) = @_; + + my $url = $self->{management_endpoint} . "/subscriptions/" . $self->{subscription} . "/resourcegroups/" . + $options{resource_group} . "/providers/Microsoft.RecoveryServices/vaults/" . + $options{vault_name} . "/backupProtectedItems?api-version=" . $self->{api_version}; + + return $url; +} + +sub azure_list_backup_items { + my ($self, %options) = @_; + + my $results = {}; + my $full_url = $self->azure_list_backup_items_set_url(%options); + my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => ''); + + return $response->{value}; +} + 1; __END__ diff --git a/centreon-plugins/cloud/azure/custom/azcli.pm b/centreon-plugins/cloud/azure/custom/azcli.pm index 3b5da9f1b..82fb1af45 100644 --- a/centreon-plugins/cloud/azure/custom/azcli.pm +++ b/centreon-plugins/cloud/azure/custom/azcli.pm @@ -110,6 +110,28 @@ sub check_options { return 0; } +sub convert_duration { + my ($self, %options) = @_; + + my $duration; + if ($options{time_string} =~ /^P.*S$/) { + centreon::plugins::misc::mymodule_load(module => 'DateTime::Format::Duration::ISO8601', + error_msg => "Cannot load module 'DateTime::Format::Duration::ISO8601'."); + + my $format = DateTime::Format::Duration::ISO8601->new; + my $d = $format->parse_duration($options{time_string}); + $duration = $d->minutes * 60 + $d->seconds; + } elsif ($options{time_string} =~ /^(\d+):(\d+):(\d+)\.\d+$/) { + centreon::plugins::misc::mymodule_load(module => 'DateTime::Duration', + error_msg => "Cannot load module 'DateTime::Format::Duration'."); + + my $d = DateTime::Duration->new(hours => $1, minutes => $2, seconds => $3); + $duration = $d->minutes * 60 + $d->seconds; + } + + return $duration; +} + sub azure_get_metrics_set_cmd { my ($self, %options) = @_; @@ -393,6 +415,127 @@ sub azure_list_deployments { return $raw_results; } +sub azure_list_vaults_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "backup vault list --output json"; + $cmd_options .= " --resource-group '$options{resource_group}'" if (defined($options{resource_group}) && $options{resource_group} ne ''); + $cmd_options .= " --subscription '$self->{subscription}'" if (defined($self->{subscription}) && $self->{subscription} ne ''); + + return $cmd_options; +} + +sub azure_list_vaults { + my ($self, %options) = @_; + + my $results = {}; + + my $cmd_options = $self->azure_list_vaults_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_backup_jobs_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "backup job list --resource-group '$options{resource_group}' --vault-name '$options{vault_name}' --output json"; + $cmd_options .= " --subscription '$self->{subscription}'" if (defined($self->{subscription}) && $self->{subscription} ne ''); + + return $cmd_options; +} + +sub azure_list_backup_jobs { + my ($self, %options) = @_; + + my $results = {}; + + my $cmd_options = $self->azure_list_backup_jobs_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_backup_items_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "backup item list --resource-group '$options{resource_group}' --vault-name '$options{vault_name}' --output json"; + $cmd_options .= " --subscription '$self->{subscription}'" if (defined($self->{subscription}) && $self->{subscription} ne ''); + + return $cmd_options; +} + +sub azure_list_backup_items { + my ($self, %options) = @_; + + my $results = {}; + + my $cmd_options = $self->azure_list_backup_items_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__ diff --git a/centreon-plugins/cloud/azure/management/recovery/mode/backupitemsstatus.pm b/centreon-plugins/cloud/azure/management/recovery/mode/backupitemsstatus.pm new file mode 100644 index 000000000..23498e9ca --- /dev/null +++ b/centreon-plugins/cloud/azure/management/recovery/mode/backupitemsstatus.pm @@ -0,0 +1,224 @@ +# +# Copyright 2019 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::management::recovery::mode::backupitemsstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Pre-Check Status '%s', Last Backup Status '%s'", + $self->{result_values}->{precheck_status}, + $self->{result_values}->{last_backup_status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{precheck_status} = $options{new_datas}->{$self->{instance} . '_precheck_status'}; + $self->{result_values}->{last_backup_status} = $options{new_datas}->{$self->{instance} . '_last_backup_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Backup Items "; +} + +sub prefix_item_output { + my ($self, %options) = @_; + + return "Backup Item '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', cb_init => 'skip_global' }, + { name => 'items', type => 1, cb_prefix_output => 'prefix_item_output', message_multiple => 'All items are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-completed', set => { + key_values => [ { name => 'completed' } ], + output_template => "completed : %s", + perfdatas => [ + { label => 'total_completed', value => 'completed_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}->{items} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'precheck_status' }, { name => 'last_backup_status' }, { 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 => \&catalog_status_threshold, + } + }, + ]; +} + +sub skip_global { + my ($self, %options) = @_; + + scalar(keys %{$self->{items}}) == 1 ? return(1) : return(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 => + { + "vault-name:s" => { name => 'vault_name' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-name:s" => { name => 'filter_name' }, + "filter-counters:s" => { name => 'filter_counters' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{precheck_status} ne "Passed" || %{last_backup_status} eq "Failed"' }, + }); + + 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(); + } + if (!defined($self->{option_results}->{vault_name}) || $self->{option_results}->{vault_name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --vault-name option"); + $self->{output}->option_exit(); + } + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { + completed => 0, failed => 0, inprogress => 0, + }; + $self->{items} = {}; + my $items = $options{custom}->azure_list_backup_items( + vault_name => $self->{option_results}->{vault_name}, + resource_group => $self->{option_results}->{resource_group} + ); + foreach my $item (@{$items}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $item->{properties}->{friendlyName} !~ /$self->{option_results}->{filter_name}/); + + $self->{items}->{$item->{id}} = { + display => $item->{properties}->{friendlyName}, + precheck_status => $item->{properties}->{healthStatus}, + last_backup_status => $item->{properties}->{lastBackupStatus}, + }; + + foreach my $status (keys %{$self->{global}}) { + $self->{global}->{$status}++ if ($item->{properties}->{lastBackupStatus} =~ /$status/i); + } + } + + if (scalar(keys %{$self->{items}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No backup items found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check backup items status. + +Example: +perl centreon_plugins.pl --plugin=cloud::azure::management::recovery::plugin --custommode=azcli --mode=backup-items-status +--resource-group='MYRESOURCEGROUP' --vault-name='Loki' --filter-counters='^total-failed$' --critical-total-failed='0' --verbose + +=over 8 + +=item B<--vault-name> + +Set vault name (Required). + +=item B<--resource-group> + +Set resource group (Required). + +=item B<--filter-name> + +Filter item name (Can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-completed$' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{precheck_status}, %{last_backup_status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{precheck_status} ne "Passed" || %{last_backup_status} eq "Failed"'). +Can used special variables like: %{precheck_status}, %{last_backup_status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-completed', 'total-failed', 'total-inprogress'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-completed', 'total-failed', 'total-inprogress'. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/management/recovery/mode/backupjobsstatus.pm b/centreon-plugins/cloud/azure/management/recovery/mode/backupjobsstatus.pm new file mode 100644 index 000000000..e84da395d --- /dev/null +++ b/centreon-plugins/cloud/azure/management/recovery/mode/backupjobsstatus.pm @@ -0,0 +1,233 @@ +# +# Copyright 2019 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::management::recovery::mode::backupjobsstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Status '%s' [Duration: %s]", $self->{result_values}->{status}, + $self->{result_values}->{duration}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{duration} = centreon::plugins::misc::change_seconds(value => $options{new_datas}->{$self->{instance} . '_duration'}); + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Backup Jobs "; +} + +sub prefix_job_output { + my ($self, %options) = @_; + + return "Backup Job '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', cb_init => 'skip_global' }, + { name => 'jobs', type => 1, cb_prefix_output => 'prefix_job_output', message_multiple => 'All jobs are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-completed', set => { + key_values => [ { name => 'completed' } ], + output_template => "completed : %s", + perfdatas => [ + { label => 'total_completed', value => 'completed_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 }, + ], + } + }, + { label => 'total-inprogress', set => { + key_values => [ { name => 'inprogress' } ], + output_template => "in progress : %s", + perfdatas => [ + { label => 'total_inprogress', value => 'inprogress_absolute', template => '%d', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{jobs} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'duration' }, { 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 => \&catalog_status_threshold, + } + }, + ]; +} + +sub skip_global { + my ($self, %options) = @_; + + scalar(keys %{$self->{jobs}}) == 1 ? return(1) : return(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 => + { + "vault-name:s" => { name => 'vault_name' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-name:s" => { name => 'filter_name' }, + "filter-counters:s" => { name => 'filter_counters' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} eq "Failed"' }, + }); + + 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(); + } + if (!defined($self->{option_results}->{vault_name}) || $self->{option_results}->{vault_name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --vault-name option"); + $self->{output}->option_exit(); + } + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { + completed => 0, failed => 0, inprogress => 0, + }; + $self->{jobs} = {}; + my $jobs = $options{custom}->azure_list_backup_jobs( + vault_name => $self->{option_results}->{vault_name}, + resource_group => $self->{option_results}->{resource_group} + ); + foreach my $job (@{$jobs}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $job->{properties}->{entityFriendlyName} !~ /$self->{option_results}->{filter_name}/); + + my $duration = $options{custom}->convert_duration(time_string => $job->{properties}->{duration}); + + $self->{jobs}->{$job->{id}} = { + display => $job->{properties}->{entityFriendlyName}, + status => $job->{properties}->{status}, + duration => $duration, + }; + + foreach my $status (keys %{$self->{global}}) { + $self->{global}->{$status}++ if ($job->{properties}->{status} =~ /$status/i); + } + } + + if (scalar(keys %{$self->{jobs}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No backup jobs found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check backup jobs status. + +Example: +perl centreon_plugins.pl --plugin=cloud::azure::management::recovery::plugin --custommode=azcli --mode=backup-jobs-status +--resource-group='MYRESOURCEGROUP' --vault-name='Loki' --filter-counters='^total-failed$' --critical-total-failed='0' --verbose + +=over 8 + +=item B<--vault-name> + +Set vault name (Required). + +=item B<--resource-group> + +Set resource group (Required). + +=item B<--filter-name> + +Filter job name (Can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-completed$' + +=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} eq "Failed"'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-completed', 'total-failed', 'total-inprogress'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-completed', 'total-failed', 'total-inprogress'. + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/management/recovery/mode/listbackupjobs.pm b/centreon-plugins/cloud/azure/management/recovery/mode/listbackupjobs.pm new file mode 100644 index 000000000..5db0ee1c0 --- /dev/null +++ b/centreon-plugins/cloud/azure/management/recovery/mode/listbackupjobs.pm @@ -0,0 +1,156 @@ +# +# Copyright 2019 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::management::recovery::mode::listbackupjobs; + +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 => + { + "vault-name:s" => { name => 'vault_name' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%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(); + } + if (!defined($self->{option_results}->{vault_name}) || $self->{option_results}->{vault_name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --vault-name option"); + $self->{output}->option_exit(); + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{jobs} = $options{custom}->azure_list_backup_jobs( + vault_name => $self->{option_results}->{vault_name}, + resource_group => $self->{option_results}->{resource_group} + ); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $job (@{$self->{jobs}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $job->{properties}->{entityFriendlyName} !~ /$self->{option_results}->{filter_name}/); + my $resource_group = '-'; + $resource_group = $job->{resourceGroup} if (defined($job->{resourceGroup})); + $resource_group = $1 if ($resource_group eq '-' && defined($job->{id}) && $job->{id} =~ /resource[gG]roups\/(.*)\/providers/); + + my @tags; + foreach my $tag (keys %{$job->{tags}}) { + push @tags, $tag . ':' . $job->{tags}->{$tag}; + } + + $self->{output}->output_add(long_msg => sprintf("[name = %s][resourcegroup = %s][id = %s][activity_id = %s][type = %s][status = %s][tags = %s]", + $job->{properties}->{entityFriendlyName}, + $resource_group, + $job->{id}, + $job->{properties}->{activityId}, + $job->{properties}->{jobType}, + $job->{properties}->{status}, + join(',', @tags)) + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List backup jobs:'); + $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', 'id', 'activity_id', 'type', 'status', 'tags']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $job (@{$self->{jobs}}) { + my $resource_group = '-'; + $resource_group = $job->{resourceGroup} if (defined($job->{resourceGroup})); + $resource_group = $1 if ($resource_group eq '-' && defined($job->{id}) && $job->{id} =~ /resourceGroups\/(.*)\/providers/); + + my @tags; + foreach my $tag (keys %{$job->{tags}}) { + push @tags, $tag . ':' . $job->{tags}->{$tag}; + } + + $self->{output}->add_disco_entry( + name => $job->{properties}->{entityFriendlyName}, + resourcegroup => $resource_group, + id => $job->{id}, + activity_id => $job->{properties}->{activityId}, + type => $job->{properties}->{jobType}, + status => $job->{properties}->{status}, + tags => join(',', @tags), + ); + } +} + +1; + +__END__ + +=head1 MODE + +List backup jobs. + +=over 8 + +=item B<--vault-name> + +Set vault name (Mandatory). + +=item B<--resource-group> + +Set resource group (Mandatory). + +=item B<--filter-name> + +Filter job name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/management/recovery/mode/listvaults.pm b/centreon-plugins/cloud/azure/management/recovery/mode/listvaults.pm new file mode 100644 index 000000000..818f87d47 --- /dev/null +++ b/centreon-plugins/cloud/azure/management/recovery/mode/listvaults.pm @@ -0,0 +1,137 @@ +# +# Copyright 2019 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::management::recovery::mode::listvaults; + +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-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{vaults} = $options{custom}->azure_list_vaults(resource_group => $self->{option_results}->{resource_group}); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $vault (@{$self->{vaults}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $vault->{name} !~ /$self->{option_results}->{filter_name}/); + next if (defined($self->{option_results}->{location}) && $self->{option_results}->{location} ne '' + && $vault->{location} !~ /$self->{option_results}->{location}/); + my $resource_group = '-'; + $resource_group = $vault->{resourceGroup} if (defined($vault->{resourceGroup})); + $resource_group = $1 if ($resource_group eq '-' && defined($vault->{id}) && $vault->{id} =~ /resourceGroups\/(.*)\/providers/); + + my @tags; + foreach my $tag (keys %{$vault->{tags}}) { + push @tags, $tag . ':' . $vault->{tags}->{$tag}; + } + + $self->{output}->output_add(long_msg => sprintf("[name = %s][resourcegroup = %s][location = %s][id = %s][tags = %s]", + $vault->{name}, $resource_group, $vault->{location}, $vault->{id}, join(',', @tags))); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List vaults:'); + $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', 'tags']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $vault (@{$self->{vaults}}) { + my $resource_group = '-'; + $resource_group = $vault->{resourceGroup} if (defined($vault->{resourceGroup})); + $resource_group = $1 if ($resource_group eq '-' && defined($vault->{id}) && $vault->{id} =~ /resourceGroups\/(.*)\/providers/); + + my @tags; + foreach my $tag (keys %{$vault->{tags}}) { + push @tags, $tag . ':' . $vault->{tags}->{$tag}; + } + + $self->{output}->add_disco_entry( + name => $vault->{name}, + resourcegroup => $resource_group, + location => $vault->{location}, + id => $vault->{id}, + tags => join(',', @tags), + ); + } +} + +1; + +__END__ + +=head1 MODE + +List vaults. + +=over 8 + +=item B<--resource-group> + +Set resource group. + +=item B<--location> + +Set resource location. + +=item B<--filter-name> + +Filter vault name (Can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/cloud/azure/management/recovery/plugin.pm b/centreon-plugins/cloud/azure/management/recovery/plugin.pm new file mode 100644 index 000000000..f5a2c443b --- /dev/null +++ b/centreon-plugins/cloud/azure/management/recovery/plugin.pm @@ -0,0 +1,63 @@ +# +# Copyright 2019 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::management::recovery::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} } = ( + 'backup-items-status' => 'cloud::azure::management::recovery::mode::backupitemsstatus', + 'backup-jobs-status' => 'cloud::azure::management::recovery::mode::backupjobsstatus', + 'list-backup-jobs' => 'cloud::azure::management::recovery::mode::listbackupjobs', + 'list-vaults' => 'cloud::azure::management::recovery::mode::listvaults', + ); + + $self->{custom_modes}{azcli} = 'cloud::azure::custom::azcli'; + $self->{custom_modes}{api} = 'cloud::azure::custom::api'; + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->{options}->add_options(arguments => + { + 'api-version:s' => { name => 'api_version', default => '2018-07-10' }, + }); + + $self->SUPER::init(%options); +} +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Azure backup service. + +=cut