diff --git a/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm b/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm index 2603d7473..2ab07d334 100644 --- a/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm +++ b/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm @@ -33,13 +33,13 @@ use JSON::XS; sub custom_status_output { my ($self, %options) = @_; - return 'status : ' . $self->{result_values}->{status} . ' [type: ' . $self->{result_values}->{type} . ']'; + return 'status: ' . $self->{result_values}->{status} . ' [type: ' . $self->{result_values}->{type} . ']'; } sub custom_long_output { my ($self, %options) = @_; - return 'started since : ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{elapsed}); + return 'started since: ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{elapsed}); } sub custom_long_calc { @@ -50,6 +50,7 @@ sub custom_long_calc { $self->{result_values}->{elapsed} = $options{new_datas}->{$self->{instance} . '_elapsed'}; $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_type'}; $self->{result_values}->{is_running} = $options{new_datas}->{$self->{instance} . '_is_running'}; + $self->{result_values}->{is_continuous} = $options{new_datas}->{$self->{instance} . '_is_continuous'}; return -11 if ($self->{result_values}->{is_running} != 1); @@ -65,11 +66,11 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total', nlabel => 'jobs.total.count', set => { + { label => 'total', nlabel => 'jobs.detected.count', set => { key_values => [ { name => 'total' } ], - output_template => 'Total Jobs : %s', + output_template => 'Total jobs: %s', perfdatas => [ - { label => 'total', template => '%s', min => 0 } + { template => '%s', min => 0 } ] } } @@ -77,14 +78,21 @@ sub set_counters { $self->{maps_counters}->{job} = [ { label => 'status', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'display' }, { name => 'type' }, { name => 'is_running' } ], + key_values => [ + { name => 'status' }, { name => 'display' }, + { name => 'type' }, { name => 'is_running' }, { name => 'is_continuous' } + ], closure_custom_output => $self->can('custom_status_output'), closure_custom_perfdata => sub { return 0; }, closure_custom_threshold_check => \&catalog_status_threshold } }, { label => 'long', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'display' }, { name => 'elapsed' }, { name => 'type' }, { name => 'is_running' } ], + key_values => [ + { name => 'status' }, { name => 'display' }, + { name => 'elapsed' }, { name => 'type' }, + { name => 'is_running' }, { name => 'is_continuous' } + ], closure_custom_calc => $self->can('custom_long_calc'), closure_custom_output => $self->can('custom_long_output'), closure_custom_perfdata => sub { return 0; }, @@ -96,7 +104,7 @@ sub set_counters { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { @@ -177,17 +185,23 @@ sub manage_selection { } #[ - # { name: 'xxxx', type: 0, isRunning: False, result: 0, creationTimeUTC: 1512875246.2, endTimeUTC: 1512883615.377 }, - # { name: 'xxxx', type: 0, isRunning: False, result: 1, creationTimeUTC: '', endTimeUTC: '' }, - # { name: 'xxxx', type: 1, isRunning: True, result: 0, creationTimeUTC: 1513060425.027, endTimeUTC: -2208992400 } + # { "name": "backup 1", "type": 0, "isRunning": false, "isContinuous": 0, "sessions": { "result": 0, "creationTimeUTC": 1512875246.2, "endTimeUTC": 1512883615.377 } }, + # { "name": "backup 2", "type": 0, "isRunning": false, "isContinuous": 0, "sessions": { "result": -10, "creationTimeUTC": "", "endTimeUTC": "" } }, + # { "name": "backup 3", "type": 1, "isRunning": true, "isContinuous": 0, "sessions": { "result": 0, "creationTimeUTC": 1513060425.027, "endTimeUTC": -2208992400 } } #] $self->{global} = { total => 0 }; $self->{job} = {}; my $current_time = time(); foreach my $job (@$decoded) { - $job->{creationTimeUTC} =~ s/,/\./; - $job->{endTimeUTC} =~ s/,/\./; + my $sessions = ref($job->{sessions}) eq 'ARRAY' ? $job->{sessions} : [ $job->{sessions} ]; + my $session = $sessions->[0]; + if ($job->{isContinuous} == 1 && defined($sessions->[1])) { + $session = $sessions->[1]; + } + + $session->{creationTimeUTC} =~ s/,/\./; + $session->{endTimeUTC} =~ s/,/\./; my $job_type = defined($job_type->{ $job->{type} }) ? $job_type->{ $job->{type} } : 'unknown'; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && @@ -201,27 +215,28 @@ sub manage_selection { next; } if (defined($self->{option_results}->{filter_end_time}) && $self->{option_results}->{filter_end_time} =~ /[0-9]+/ && - $job->{endTimeUTC} =~ /[0-9]+/ && $job->{endTimeUTC} < $current_time - $self->{option_results}->{filter_end_time}) { + $session->{endTimeUTC} =~ /[0-9]+/ && $session->{endTimeUTC} > 0 && $session->{endTimeUTC} < $current_time - $self->{option_results}->{filter_end_time}) { $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': end time too old.", debug => 1); next; } if (defined($self->{option_results}->{filter_start_time}) && $self->{option_results}->{filter_start_time} =~ /[0-9]+/ && - $job->{creationTimeUTC} =~ /[0-9]+/ && $job->{creationTimeUTC} < $current_time - $self->{option_results}->{filter_start_time}) { + $session->{creationTimeUTC} =~ /[0-9]+/ && $session->{creationTimeUTC} < $current_time - $self->{option_results}->{filter_start_time}) { $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': start time too old.", debug => 1); next; } my $elapsed_time; - $elapsed_time = $current_time - $job->{creationTimeUTC} if ($job->{creationTimeUTC} =~ /[0-9]/); + $elapsed_time = $current_time - $session->{creationTimeUTC} if ($session->{creationTimeUTC} =~ /[0-9]/); #is_running = 2 (never running) $self->{job}->{ $job->{name} } = { display => $job->{name}, elapsed => $elapsed_time, type => $job_type, - is_running => $job->{isRunning} =~ /True|1/ ? 1 : ($job->{creationTimeUTC} !~ /[0-9]/ ? 2 : 0), - status => defined($job_result->{ $job->{result} }) && $job_result->{ $job->{result} } ne '' ? - $job_result->{ $job->{result} } : '-' + is_continuous => $job->{isContinuous}, + is_running => $job->{isRunning} =~ /True|1/ ? 1 : ($session->{creationTimeUTC} !~ /[0-9]/ ? 2 : 0), + status => defined($job_result->{ $session->{result} }) && $job_result->{ $session->{result} } ne '' ? + $job_result->{ $session->{result} } : '-' }; $self->{global}->{total}++; } diff --git a/centreon-plugins/apps/backup/veeam/local/mode/listrepositories.pm b/centreon-plugins/apps/backup/veeam/local/mode/listrepositories.pm new file mode 100644 index 000000000..4445de0c7 --- /dev/null +++ b/centreon-plugins/apps/backup/veeam/local/mode/listrepositories.pm @@ -0,0 +1,190 @@ +# +# Copyright 2022 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 apps::backup::veeam::local::mode::listrepositories; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::backup::veeam::local::mode::resources::types qw($repository_type $repository_status); +use centreon::common::powershell::veeam::repositories; +use centreon::plugins::misc; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'timeout:s' => { name => 'timeout', default => 50 }, + 'command:s' => { name => 'command', default => 'powershell.exe' }, + 'command-path:s' => { name => 'command_path' }, + 'command-options:s' => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + 'no-ps' => { name => 'no_ps' }, + 'ps-exec-only' => { name => 'ps_exec_only' }, + 'ps-display' => { name => 'ps_display' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my $repos = $self->manage_selection(%options); + foreach (@$repos) { + $self->{output}->output_add( + long_msg => sprintf( + '[name: %s][type: %s][status: %s][totalSpace: %s]', + $_->{name}, + $_->{type}, + $_->{status}, + $_->{totalSpace} + ) + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List repositories:' + ); + $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', 'type', 'status', 'totalSpace']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $repos = $self->manage_selection(%options); + foreach (@$repos) { + $self->{output}->add_disco_entry(%$_); + } +} + +sub manage_selection { + my ($self, %options) = @_; + + if (!defined($self->{option_results}->{no_ps})) { + my $ps = centreon::common::powershell::veeam::repositories::get_powershell(); + if (defined($self->{option_results}->{ps_display})) { + $self->{output}->output_add( + severity => 'OK', + short_msg => $ps + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + $self->{option_results}->{command_options} .= " " . centreon::plugins::misc::powershell_encoded($ps); + } + + my ($stdout) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add( + severity => 'OK', + short_msg => $stdout + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + my $repos = []; + foreach (@$decoded) { + push @$repos, { + name => $_->{name}, + type => defined($repository_type->{ $_->{type} }) ? $repository_type->{ $_->{type} } : 'unknown', + status => defined($repository_status->{ $_->{status} }) ? $repository_status->{ $_->{status} } : 'unknown', + totalSpace => $_->{totalSpace} + }; + } + + return $repos; +} + +1; + +__END__ + +=head1 MODE + +List repositories. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 50 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option!!! + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-display> + +Display powershell script. + +=item B<--ps-exec-only> + +Print powershell output. + +=back + +=cut diff --git a/centreon-plugins/apps/backup/veeam/local/mode/repositories.pm b/centreon-plugins/apps/backup/veeam/local/mode/repositories.pm new file mode 100644 index 000000000..9d44bdb85 --- /dev/null +++ b/centreon-plugins/apps/backup/veeam/local/mode/repositories.pm @@ -0,0 +1,297 @@ +# +# Copyright 2022 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 apps::backup::veeam::local::mode::repositories; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::common::powershell::veeam::repositories; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use apps::backup::veeam::local::mode::resources::types qw($repository_type $repository_status); +use JSON::XS; + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf( + "status: %s", + $self->{result_values}->{status} + ); +} + +sub custom_space_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + return sprintf( + "space usage total: %s used: %s (%.2f%%) free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free} + ); +} + +sub repository_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking repository '%s' [type: %s]", + $options{instance_value}->{name}, + $options{instance_value}->{type} + ); +} + +sub prefix_repository_output { + my ($self, %options) = @_; + + return sprintf( + "repository '%s' [type: %s] ", + $options{instance_value}->{name}, + $options{instance_value}->{type} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'repositories', type => 3, cb_prefix_output => 'prefix_repository_output', cb_long_output => 'repository_long_output', + indent_long_output => ' ', message_multiple => 'All repositories are ok', + group => [ + { name => 'status', type => 0, skipped_code => { -10 => 1 } }, + { name => 'space', type => 0, skipped_code => { -10 => 1 } } + ] + } + ]; + + $self->{maps_counters}->{status} = [ + { + label => 'status', + type => 2, + critical_default => 'not %{status} =~ /ordinal|maintenance/i', + set => { + key_values => [ + { name => 'status' }, { name => 'name' }, { name => 'type' } + ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; + + $self->{maps_counters}->{space} = [ + { label => 'space-usage', nlabel => 'repository.space.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'name' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'name' } + ] + } + }, + { label => 'space-usage-free', display_ok => 0, nlabel => 'repository.space.free.bytes', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'name' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'name' } + ] + } + }, + { label => 'space-usage-prct', display_ok => 0, nlabel => 'repository.space.usage.percentage', set => { + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' }, { name => 'name' } ], + closure_custom_output => $self->can('custom_space_usage_output'), + perfdatas => [ + { template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'name' } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'timeout:s' => { name => 'timeout', default => 50 }, + 'command:s' => { name => 'command', default => 'powershell.exe' }, + 'command-path:s' => { name => 'command_path' }, + 'command-options:s' => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + 'no-ps' => { name => 'no_ps' }, + 'ps-exec-only' => { name => 'ps_exec_only' }, + 'ps-display' => { name => 'ps_display' }, + 'filter-name:s' => { name => 'filter_name' }, + 'filter-type:s' => { name => 'filter_type' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + if (!defined($self->{option_results}->{no_ps})) { + my $ps = centreon::common::powershell::veeam::repositories::get_powershell(); + if (defined($self->{option_results}->{ps_display})) { + $self->{output}->output_add( + severity => 'OK', + short_msg => $ps + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + $self->{option_results}->{command_options} .= " " . centreon::plugins::misc::powershell_encoded($ps); + } + + my ($stdout) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add( + severity => 'OK', + short_msg => $stdout + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + #[ + # {"name": "repo 1", "type": 10, "status": 0, "totalSpace": 100000000, "freeSpace": 1000000 }, + # {"name": "repo 2", "type": 11, "status": 0, "totalSpace": 250000000, "freeSpace": 1000000 } + #] + + $self->{repositories} = {}; + foreach my $repo (@$decoded) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $repo->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping repository '$repo->{name}'.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $repo->{type} !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping repository '$repo->{name}'.", debug => 1); + next; + } + + my $type = defined($repository_type->{ $repo->{type} }) ? $repository_type->{ $repo->{type} } : 'unknown'; + $self->{repositories}->{ $repo->{name} } = { + name => $repo->{name}, + type => $type, + status => { + name => $repo->{name}, + type => $type, + status => defined($repository_status->{ $repo->{status} }) ? $repository_status->{ $repo->{status} } : 'unknown' + }, + space => { + name => $repo->{name}, + total => $repo->{totalSpace}, + free => $repo->{freeSpace}, + used => $repo->{totalSpace} - $repo->{freeSpace}, + prct_used => 100 - ($repo->{freeSpace} * 100 / $repo->{totalSpace}), + prct_free => $repo->{freeSpace} * 100 / $repo->{totalSpace} + } + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check repositories. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 50 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option!!! + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-display> + +Display powershell script. + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--filter-name> + +Filter repositories by name (can be a regexp). + +=item B<--filter-type> + +Filter repositories by type (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{name}, %{type}. + +=item B<--critical-status> + +Set critical threshold for status (Default: 'not %{status} =~ /ordinal|maintenance/i'). +Can used special variables like: %{status}, %{name}, %{type}. + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'space-usage', 'space-usage-free', 'space-usage-prct'. + +=back + +=cut diff --git a/centreon-plugins/apps/backup/veeam/local/mode/resources/types.pm b/centreon-plugins/apps/backup/veeam/local/mode/resources/types.pm index b3b4a224c..20c8622a3 100644 --- a/centreon-plugins/apps/backup/veeam/local/mode/resources/types.pm +++ b/centreon-plugins/apps/backup/veeam/local/mode/resources/types.pm @@ -31,11 +31,14 @@ our $job_tape_result; our $job_tape_state; our $license_type; our $license_status; +our $repository_type; +our $repository_status; our @ISA = qw(Exporter); our @EXPORT_OK = qw( $job_type $job_result $job_tape_type $job_tape_result $job_tape_state $license_type $license_status + $repository_type $repository_status ); $job_type = { @@ -135,4 +138,29 @@ $license_status = { 0 => 'valid', 1 => 'expired', 2 => 'invalid' }; +$repository_type = { + 0 => 'WinLocal', 1 => 'LinuxLocal', + 2 => 'CifsShare', 3 => 'DDBoost', + 4 => 'Cloud', 5 => 'HPStoreOnce', + 6 => 'ExaGrid', 7 => 'Foreign', + 8 => 'SanSnapshotOnly', 9 => 'HPStoreOnceIntegration', + 10 => 'ExtendableRepository', 11 => 'AmazonS3', + 12 => 'AzureStorage', 13 => 'AmazonS3Glacier', + 14 => 'AmazonS3Compatible', 15 => 'Tape', + 16 => 'AmazonS3External', 17 => 'AzureStorageExternal', + 18 => 'Quantum', 19 => 'IbmCosS3', + 20 => 'Nfs', 21 => 'AzureDataBox', + 22 => 'PlatformServiceExternal', 23 => 'GoogleCloudStorage', + 24 => 'AzureArchiveStorage', 25 => 'AmazonSnowball', + 26 => 'GoogleCloudStorageExternal', 27 => 'SmartObjectS3', + 31 => 'AmazonS3GlacierExternal', 32 => 'GoogleArchiveStorageExternal', + 33 => 'AzureArchiveStorageExternal' +}; + +$repository_status = { + 0 => 'ordinal', 1 => 'maintenancePending', + 2 => 'maintenance', 4 => 'evacuating', + 8 => 'sealed' +}; + 1; diff --git a/centreon-plugins/apps/backup/veeam/local/plugin.pm b/centreon-plugins/apps/backup/veeam/local/plugin.pm index 4706f7076..9e3d116a9 100644 --- a/centreon-plugins/apps/backup/veeam/local/plugin.pm +++ b/centreon-plugins/apps/backup/veeam/local/plugin.pm @@ -29,13 +29,14 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '0.1'; $self->{modes} = { - 'job-status' => 'apps::backup::veeam::local::mode::jobstatus', - 'licenses' => 'apps::backup::veeam::local::mode::licenses', - 'list-jobs' => 'apps::backup::veeam::local::mode::listjobs', - 'tape-jobs' => 'apps::backup::veeam::local::mode::tapejobs', - 'vsb-jobs' => 'apps::backup::veeam::local::mode::vsbjobs' + 'job-status' => 'apps::backup::veeam::local::mode::jobstatus', + 'licenses' => 'apps::backup::veeam::local::mode::licenses', + 'list-jobs' => 'apps::backup::veeam::local::mode::listjobs', + 'list-repositories' => 'apps::backup::veeam::local::mode::listrepositories', + 'repositories' => 'apps::backup::veeam::local::mode::repositories', + 'tape-jobs' => 'apps::backup::veeam::local::mode::tapejobs', + 'vsb-jobs' => 'apps::backup::veeam::local::mode::vsbjobs' }; return $self; diff --git a/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm b/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm index c66dcebdf..a6871f2e0 100644 --- a/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm +++ b/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm @@ -49,12 +49,20 @@ Try { $sessions = @{} Get-VBRBackupSession | Sort CreationTimeUTC -Descending | ForEach-Object { - $jobId = $_.jobId.toString() + $jobId = $_.jobId.toString() if (-not $sessions.ContainsKey($jobId)) { - $sessions[$jobId] = @{} - $sessions[$jobId].result = $_.Result.value__ - $sessions[$jobId].creationTimeUTC = (get-date -date $_.CreationTime.ToUniversalTime() -Uformat ' . "'%s'" . ') - $sessions[$jobId].endTimeUTC = (get-date -date $_.EndTime.ToUniversalTime() -Uformat ' . "'%s'" . ') + $sessions[$jobId] = New-Object System.Collections.Generic.List[Hashtable]; + $session = @{} + $session.result = $_.Result.value__ + $session.creationTimeUTC = (get-date -date $_.CreationTimeUTC.ToUniversalTime() -Uformat ' . "'%s'" . ') + $session.endTimeUTC = (get-date -date $_.EndTimeUTC.ToUniversalTime() -Uformat ' . "'%s'" . ') + $sessions[$jobId].Add($session) + } elseif ($sessions[$jobId].Length -lt 2) { + $session = @{} + $session.result = $_.Result.value__ + $session.creationTimeUTC = (get-date -date $_.CreationTimeUTC.ToUniversalTime() -Uformat ' . "'%s'" . ') + $session.endTimeUTC = (get-date -date $_.EndTimeUTC.ToUniversalTime() -Uformat ' . "'%s'" . ') + $sessions[$jobId].Add($session) } } @@ -63,15 +71,22 @@ Try { $item.name = $_.Name $item.type = $_.JobType.value__ $item.isRunning = $_.isRunning - $item.result = -10 - $item.creationTimeUTC = "" - $item.endTimeUTC = "" + $item.isContinuous = 0 + + if ($_.isContinuous -eq $true) { + $item.isContinuous = 1 + } - $guid = $_.Id.Guid.toString() + $guid = $_.Id.Guid.toString() if ($sessions.ContainsKey($guid)) { - $item.result = $sessions[$guid].result - $item.creationTimeUTC = $sessions[$guid].creationTimeUTC - $item.endTimeUTC = $sessions[$guid].endTimeUTC + $item.sessions = $sessions[$guid] + } else { + $item.sessions = New-Object System.Collections.Generic.List[Hashtable]; + $session = @{} + $session.result = -10 + $session.creationTimeUTC = "" + $session.endTimeUTC = "" + $item.sessions.Add($session) } $items.Add($item) diff --git a/centreon-plugins/centreon/common/powershell/veeam/repositories.pm b/centreon-plugins/centreon/common/powershell/veeam/repositories.pm new file mode 100644 index 000000000..ef7a8ec58 --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/veeam/repositories.pm @@ -0,0 +1,84 @@ +# +# Copyright 2022 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 centreon::common::powershell::veeam::repositories; + +use strict; +use warnings; +use centreon::common::powershell::functions; +use centreon::common::powershell::veeam::functions; + +sub get_powershell { + my (%options) = @_; + + my $ps = ' +$ProgressPreference = "SilentlyContinue" +$WarningPreference = "SilentlyContinue" + +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture +'; + + $ps .= centreon::common::powershell::functions::escape_jsonstring(%options); + $ps .= centreon::common::powershell::functions::convert_to_json(%options); + $ps .= centreon::common::powershell::veeam::functions::powershell_init(); + + $ps .= ' +Try { + $ErrorActionPreference = "Stop" + + $items = New-Object System.Collections.Generic.List[Hashtable]; + + Get-VBRBackupRepository | ForEach-Object { + $container = $_.GetContainer() + + $item = @{ + name = $_.Name; + type = $_.Type.value__; + status = $_.Status.value__ + } + $item.totalSpace = $container.CachedTotalSpace.inBytes.ToString() + $item.freeSpace = $container.CachedFreeSpace.inBytes.ToString() + + $items.Add($item) + } + + $jsonString = $items | ConvertTo-JSON-20 -forceArray $true + Write-Host $jsonString +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return $ps; +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get veeam repositories informations. + +=cut diff --git a/centreon-plugins/centreon/common/powershell/veeam/vsbjobs.pm b/centreon-plugins/centreon/common/powershell/veeam/vsbjobs.pm index 7e5bb8935..814da917e 100644 --- a/centreon-plugins/centreon/common/powershell/veeam/vsbjobs.pm +++ b/centreon-plugins/centreon/common/powershell/veeam/vsbjobs.pm @@ -53,8 +53,8 @@ Try { if (-not $sessions.ContainsKey($jobId)) { $sessions[$jobId] = @{} $sessions[$jobId].result = $_.Result.value__ - $sessions[$jobId].creationTimeUTC = (get-date -date $_.CreationTime.ToUniversalTime() -Uformat ' . "'%s'" . ') - $sessions[$jobId].endTimeUTC = (get-date -date $_.EndTime.ToUniversalTime() -Uformat ' . "'%s'" . ') + $sessions[$jobId].creationTimeUTC = (get-date -date $_.CreationTimeUTC.ToUniversalTime() -Uformat ' . "'%s'" . ') + $sessions[$jobId].endTimeUTC = (get-date -date $_.EndTimeUTC.ToUniversalTime() -Uformat ' . "'%s'" . ') } }