diff --git a/centreon-plugins/apps/backup/backupexec/local/mode/alerts.pm b/centreon-plugins/apps/backup/backupexec/local/mode/alerts.pm new file mode 100644 index 000000000..baca9d3d2 --- /dev/null +++ b/centreon-plugins/apps/backup/backupexec/local/mode/alerts.pm @@ -0,0 +1,279 @@ +# +# 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::backupexec::local::mode::alerts; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::common::powershell::backupexec::alerts; +use apps::backup::backupexec::local::mode::resources::types qw($alert_severity $alert_source $alert_category); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use centreon::plugins::misc; +use JSON::XS; + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf( + "alert %s [severity: %s] [source: %s] [category: %s] [raised: %s] %s", + $self->{result_values}->{name}, + $self->{result_values}->{severity}, + $self->{result_values}->{source}, + $self->{result_values}->{category}, + scalar(localtime($self->{result_values}->{timeraised})), + $self->{result_values}->{message} + ); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Alerts severity '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { + name => 'alarms', type => 2, message_multiple => '0 alerts detected', format_output => '%s alerts detected', display_counter_problem => { nlabel => 'alerts.detected.count', min => 0 }, + group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ] + } + ]; + + $self->{maps_counters}->{global} = []; + foreach ('none', 'information', 'question', 'warning', 'error') { + push @{$self->{maps_counters}->{global}}, { + label => 'severity-' . $_, nlabel => 'alerts.severity.' . $_ . '.count', display_ok => 0, set => { + key_values => [ { name => $_ } ], + output_template => $_ . ': %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + }; + } + + $self->{maps_counters}->{alarm} = [ + { + label => 'status', + type => 2, + warning_default => '%{severity} =~ /warning/i', + critical_default => '%{severity} =~ /error/i', + set => { + key_values => [ + { name => 'timeraised' }, { name => 'category' }, + { name => 'severity' }, { name => 'source' }, + { name => 'message' }, { name => 'name' } + ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +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' }, + 'bemcli-file' => { name => 'bemcli_file' }, + 'filter-category:s' => { name => 'filter_category' }, + 'filter-source:s' => { name => 'filter_source' }, + 'filter-severity:s' => { name => 'filter_severity' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + if (!defined($self->{option_results}->{no_ps})) { + my $ps = centreon::common::powershell::backupexec::alerts::get_powershell( + bemcli_file => $self->{option_results}->{bemcli_file} + ); + 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": "alert 1", "severity": 1, "source": 0, "category": 1, "message": "test 1", "creationTime": 1512875246.2 }, + # { "name": "alert 2", "severity": 3, "source": 2, "category": 8, "message": "test 2", "creationTime": "1512875246.2" } + #] + + $self->{global} = { none => 0, information => 0, question => 0, warning => 0, error => 0 }; + $self->{alarms}->{global} = { alarm => {} }; + my $i = 0; + foreach my $alert (@$decoded) { + my $severity = defined($alert_severity->{ $alert->{severity} }) ? $alert_severity->{ $alert->{severity} } : 'unknown'; + my $category = defined($alert_category->{ $alert->{category} }) ? $alert_category->{ $alert->{category} } : 'unknown'; + my $source = defined($alert_source->{ $alert->{source} }) ? $alert_source->{ $alert->{source} } : 'unknown'; + $alert->{creationTime} =~ s/,/\./; + + if (defined($self->{option_results}->{filter_category}) && $self->{option_results}->{filter_category} ne '' && + $category !~ /$self->{option_results}->{filter_category}/) { + $self->{output}->output_add(long_msg => "skipping '" . $alert->{name} . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_severity}) && $self->{option_results}->{filter_severity} ne '' && + $severity !~ /$self->{option_results}->{filter_severity}/) { + $self->{output}->output_add(long_msg => "skipping '" . $alert->{name} . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_source}) && $self->{option_results}->{filter_source} ne '' && + $source !~ /$self->{option_results}->{filter_source}/) { + $self->{output}->output_add(long_msg => "skipping '" . $alert->{name} . "': no matching filter.", debug => 1); + next; + } + + $self->{global}->{$severity}++; + $self->{alarms}->{global}->{alarm}->{$i} = { + name => $alert->{name}, + source => $source, + category => $category, + severity => $severity, + message => $alert->{message}, + timeraised => $alert->{creationTime} + }; + $i++; + } +} + +1; + +__END__ + +=head1 MODE + +Check alerts. + +=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<--bemcli-file> + +Set powershell module file (default: 'C:/Program Files/Veritas/Backup Exec/Modules/BEMCLI/bemcli'). + +=item B<--filter-category> + +Only get alerts by category (can be a regexp). + +=item B<--filter-source> + +Filter alerts by source (can be a regexp). + +=item B<--filter-severity> + +Only get alerts by severity (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{severity} =~ /warning/i') +Can used special variables like: %{name}, %{severity}, %{source}, %{category}, %{timeraised}, %{message} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{severity} =~ /error/i'). +Can used special variables like: %{name}, %{severity}, %{source}, %{category}, %{timeraised}, %{message} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'severity-none', 'severity-information', 'severity-question', +'severity-warning', 'severity-error'. + +=back + +=cut diff --git a/centreon-plugins/apps/backup/backupexec/local/mode/disks.pm b/centreon-plugins/apps/backup/backupexec/local/mode/disks.pm new file mode 100644 index 000000000..d7e520d53 --- /dev/null +++ b/centreon-plugins/apps/backup/backupexec/local/mode/disks.pm @@ -0,0 +1,304 @@ +# +# 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::backupexec::local::mode::disks; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::common::powershell::backupexec::disks; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use apps::backup::backupexec::local::mode::resources::types qw($storage_type); +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 disk_long_output { + my ($self, %options) = @_; + + return sprintf( + "checking disk '%s' [type: %s]", + $options{instance_value}->{name}, + $options{instance_value}->{type} + ); +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return sprintf( + "disk '%s' [type: %s] ", + $options{instance_value}->{name}, + $options{instance_value}->{type} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'disks', type => 3, cb_prefix_output => 'prefix_disk_output', cb_long_output => 'disk_long_output', + indent_long_output => ' ', message_multiple => 'All disks 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, + 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' }, + 'bemcli-file' => { name => 'bemcli_file' }, + '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::backupexec::disks::get_powershell( + bemcli_file => $self->{option_results}->{bemcli_file} + ); + 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": "disk 1", "type": 3, "disabled": false, "totalSpace": 100000000, "usedSpace": 1000000 }, + # { "name": "disk 2", "type": 5, "disabled": false, "totalSpace": 250000000, "usedSpace": 1000000 } + #] + + $self->{disks} = {}; + foreach my $disk (@$decoded) { + my $type = defined($storage_type->{ $disk->{type} }) ? $storage_type->{ $disk->{type} } : 'unknown'; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $disk->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping disk '$disk->{name}'.", debug => 1); + next; + } + 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 => "skipping disk '$disk->{name}'.", debug => 1); + next; + } + + $self->{disks}->{ $disk->{name} } = { + name => $disk->{name}, + type => $type, + status => { + name => $disk->{name}, + type => $type, + status => $disk->{disabled} =~ /True|1/i ? 'disabled' : 'enabled' + }, + space => { + name => $disk->{name}, + total => $disk->{totalSpace}, + free => 100 - $disk->{usedSpace}, + used => $disk->{usedSpace}, + prct_used => $disk->{usedSpace} * 100 / $disk->{totalSpace}, + prct_free => 100 - ($disk->{usedSpace} * 100 / $disk->{totalSpace}) + } + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check disks. + +=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<--bemcli-file> + +Set powershell module file (default: 'C:/Program Files/Veritas/Backup Exec/Modules/BEMCLI/bemcli'). + +=item B<--filter-name> + +Filter disks by name (can be a regexp). + +=item B<--filter-type> + +Filter disks 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. +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/backupexec/local/mode/jobs.pm b/centreon-plugins/apps/backup/backupexec/local/mode/jobs.pm new file mode 100644 index 000000000..8a8d060fb --- /dev/null +++ b/centreon-plugins/apps/backup/backupexec/local/mode/jobs.pm @@ -0,0 +1,320 @@ +# +# 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::backupexec::local::mode::jobs; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::common::powershell::backupexec::jobs; +use apps::backup::backupexec::local::mode::resources::types qw($job_status $job_substatus $job_type); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); +use centreon::plugins::misc; +use JSON::XS; + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf( + 'status: %s [substatus: %s] [type: %s]', + $self->{result_values}->{status}, + $self->{result_values}->{subStatus}, + $self->{result_values}->{type} + ); +} + +sub custom_long_output { + my ($self, %options) = @_; + + return 'started since: ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{elapsed}); +} + +sub custom_long_calc { + my ($self, %options) = @_; + + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{subStatus} = $options{new_datas}->{$self->{instance} . '_subStatus'}; + $self->{result_values}->{elapsed} = $options{new_datas}->{$self->{instance} . '_elapsed'}; + $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_type'}; + $self->{result_values}->{isActive} = $options{new_datas}->{$self->{instance} . '_isActive'}; + + return -11 if ($self->{result_values}->{isActive} != 1); + + return 0; +} + +sub prefix_job_output { + my ($self, %options) = @_; + + return "Job '" . $options{instance_value}->{name} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'jobs', type => 1, cb_prefix_output => 'prefix_job_output', message_multiple => 'All jobs are ok', skipped_code => { -11 => 1, -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'detected', nlabel => 'jobs.detected.count', set => { + key_values => [ { name => 'detected' } ], + output_template => 'Jobs detected: %s', + perfdatas => [ + { template => '%s', min => 0 } + ] + } + } + ]; + + $self->{maps_counters}->{jobs} = [ + { label => 'status', type => 2, critical_default => 'not %{status} =~ /succeeded/i', set => { + key_values => [ + { name => 'name' }, { name => 'type' }, + { name => 'status' }, { name => 'subStatus' }, + { name => 'isActive' } + ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'long', type => 2, set => { + key_values => [ + { name => 'name' }, { name => 'type' }, + { name => 'status' }, { name => 'subStatus' }, + { name => 'elapsed' }, { name => 'isActive' } + ], + closure_custom_calc => $self->can('custom_long_calc'), + closure_custom_output => $self->can('custom_long_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + } + ]; +} + +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' }, + 'bemcli-file' => { name => 'bemcli_file' }, + 'filter-name:s' => { name => 'filter_name' }, + 'filter-type:s' => { name => 'filter_type' }, + 'filter-end-time:s' => { name => 'filter_end_time', default => 86400 }, + 'filter-start-time:s' => { name => 'filter_start_time' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + if (!defined($self->{option_results}->{no_ps})) { + my $ps = centreon::common::powershell::backupexec::jobs::get_powershell( + bemcli_file => $self->{option_results}->{bemcli_file} + ); + 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": "backup 1", "type": 1, "status": 9, "subStatus": 0, "isActive": false, "creationTimeUTC": 1512875246.2, "endTimeUTC": 1512883615.377, "elapsedTime": 120 }, + # { "name": "backup 2", "type": 2, "status": 0, "subStatus": 1, "isActive": true, "creationTimeUTC": "1512875246.2", "endTimeUTC": "", "elapsedTime": 10000 } + #] + + $self->{global} = { detected => 0 }; + $self->{jobs} = {}; + my $current_time = time(); + foreach my $job (@$decoded) { + $job->{creationTimeUTC} =~ s/,/\./; + $job->{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 '' && + $job->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $job_type !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': no matching filter type.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_end_time}) && $self->{option_results}->{filter_end_time} =~ /[0-9]+/ && + $job->{endTimeUTC} =~ /[0-9]+/ && $job->{endTimeUTC} > 0 && $job->{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}) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': start time too old.", debug => 1); + next; + } + + #isActive = 2 (never running) + $self->{jobs}->{ $job->{name} } = { + name => $job->{name}, + elapsed => $job->{elapsedTime}, + type => $job_type, + isActive => $job->{isActive} =~ /True|1/i ? 1 : ($job->{creationTimeUTC} !~ /[0-9]/ ? 2 : 0), + status => defined($job_status->{ $job->{status} }) ? $job_status->{ $job->{status} } : '-', + subStatus => defined($job_substatus->{ $job->{subStatus} }) ? $job_substatus->{ $job->{subStatus} } : '-' + }; + $self->{global}->{detected}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check jobs. + +=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<--bemcli-file> + +Set powershell module file (default: 'C:/Program Files/Veritas/Backup Exec/Modules/BEMCLI/bemcli'). + +=item B<--filter-name> + +Filter job name (can be a regexp). + +=item B<--filter-type> + +Filter job type (can be a regexp). + +=item B<--filter-start-time> + +Filter job with start time greater than current time less value in seconds. + +=item B<--filter-end-time> + +Filter job with end time greater than current time less value in seconds (Default: 86400). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}. + +=item B<--critical-status> + +Set critical threshold for status (Default: 'not %{status} =~ /succeeded/i'). +Can used special variables like: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}. + +=item B<--warning-long> + +Set warning threshold for long jobs. +Can used special variables like: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}, %{elapsed}. + +=item B<--critical-long> + +Set critical threshold for long jobs. +Can used special variables like: %{name}, %{status}, %{subStatus}, %{type}, %{isActive}, %{elapsed}. + +=item B<--warning-detected> + +Set warning threshold for detected jobs. + +=item B<--critical-detected> + +Set critical threshold for detected jobs. + +=back + +=cut diff --git a/centreon-plugins/apps/backup/backupexec/local/mode/listdisks.pm b/centreon-plugins/apps/backup/backupexec/local/mode/listdisks.pm new file mode 100644 index 000000000..187048081 --- /dev/null +++ b/centreon-plugins/apps/backup/backupexec/local/mode/listdisks.pm @@ -0,0 +1,197 @@ +# +# 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::backupexec::local::mode::listdisks; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use apps::backup::backupexec::local::mode::resources::types qw($storage_type); +use centreon::common::powershell::backupexec::disks; +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' }, + 'bemcli-file' => { name => 'bemcli_file' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my $disks = $self->manage_selection(%options); + foreach (@$disks) { + $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 disks:' + ); + $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 $disks = $self->manage_selection(%options); + foreach (@$disks) { + $self->{output}->add_disco_entry(%$_); + } +} + +sub manage_selection { + my ($self, %options) = @_; + + if (!defined($self->{option_results}->{no_ps})) { + my $ps = centreon::common::powershell::backupexec::disks::get_powershell( + bemcli_file => $self->{option_results}->{bemcli_file} + ); + 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 $disks = []; + foreach (@$decoded) { + push @$disks, { + name => $_->{name}, + type => defined($storage_type->{ $_->{type} }) ? $storage_type->{ $_->{type} } : 'unknown', + status => $_->{disabled} =~ /True|1/i ? 'disabled' : 'enabled', + totalSpace => $_->{totalSpace} + }; + } + + return $disks; +} + +1; + +__END__ + +=head1 MODE + +List disks. + +=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<--bemcli-file> + +Set powershell module file (default: 'C:/Program Files/Veritas/Backup Exec/Modules/BEMCLI/bemcli'). + +=back + +=cut diff --git a/centreon-plugins/apps/backup/backupexec/local/mode/resources/types.pm b/centreon-plugins/apps/backup/backupexec/local/mode/resources/types.pm new file mode 100644 index 000000000..cc8862b90 --- /dev/null +++ b/centreon-plugins/apps/backup/backupexec/local/mode/resources/types.pm @@ -0,0 +1,140 @@ +# +# 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::backupexec::local::mode::resources::types; + +use strict; +use warnings; +use Exporter; + +our $job_status; +our $job_substatus; +our $job_type; +our $storage_type; +our $alert_severity; +our $alert_source; +our $alert_category; + +our @ISA = qw(Exporter); +our @EXPORT_OK = qw( + $job_status $job_substatus $job_type + $storage_type + $alert_severity $alert_source $alert_category +); + +$job_status = { + 0 => 'unknown', 1 => 'Canceled', + 2 => 'completed', 3 => 'succeededWithExceptions', + 4 => 'onHold', 5 => 'error', 6 => 'missed', + 7 => 'recovered', 8 => 'resumed', 9 => 'succeeded', + 10 => 'thresholdAbort', 11 => 'dispatched', + 12 => 'dispatchFailed', 13 => 'invalidSchedule', + 14 => 'invalidTimeWindow', 15 => 'notInTimeWindow', + 16 => 'queued', 17 => 'disabled', + 18 => 'active', 19 => 'ready', + 20 => 'scheduled', 21 => 'superseded', + 22 => 'toBeScheduled', 23 => 'linked', + 24 => 'ruleBlocked', +}; + +$job_substatus = { + 0 => 'unknown', 1 => 'ok', 2 => 'internalError', 3 => 'invalidInput', + 4 => 'InvalidStorageDevice', 5 => 'invalidJob', 6 => 'destinationCannotBeABackupExecServer', + 7 => 'storageCannotBeStorageDevicePool', 8 => 'noBackupExecServersAvailable', + 9 => 'notReadyDiscoveringStorageDevices', 10 => 'incompatibleResumes', + 11 => 'serverLicenseNotAvailable', 12 => 'multiServerLicenseNotAvailable', + 13 => 'advancedOpenFileOptionLicenseNotAvailable', 14 => 'sqlAgentLicenseNotAvailable', + 15 => 'exchangeAgentLicenseNotAvailable', 16 => 'windows2000LicenseNotAvailable', + 17 => 'netwareLicenseNotAvailable', 18 => 'noWindowsNT4Server', 19 => 'noWindows2000Server', + 20 => 'noNetwareServer', 21 => 'localBackupExecServerRequired', 22 => 'lotusNotesLicenseNotAvailable', + 23 => 'oracleAgentLicenseNotAvailable', 24 => 'lotusDominoAgentLicenseNotAvailable', 25 => 'sharepointAgentLicenseNotAvailable', + 26 => 'noServersInBackupExecServerPool', 27 => 'localServerNotBackupExecServer', 28 => 'destinationServerNotInBackupExecServerPool', + 29 => 'storageDeviceNotOnLocalBackupExecServer', 30 => 'storageNotConfiguredForBackupExecServer', + 31 => 'unixAgentLicenseNotAvailable', 32 => 'macintoshAgentLicenseNotAvailable', + 33 => 'noIdleDevicesAvailable', 34 => 'cascadedPoolNotAllowed', 35 => 'cascadedPoolIsEmpty', + 36 => 'storageDevicePoolIsEmpty', 37 => 'noDevicesInCascadedPoolAreAvailable', 38 => 'noEligibleDevicesAvailableInStorageDevicePool', + 39 => 'willRunAfterBlockingJobCompletes', 40 => 'jobQueueOnHold', 41 => 'backupExecServerNotAvailable', + 42 => 'oracleOnLinuxAgentLicenseNotAvailable', 43 => 'blockedByActiveLinkedJob', + 44 => 'db2AgentLicenseNotAvailable', 45 => 'microsoftVirtualServerAgentLicenseNotAvailable', + 46 => 'vmwareAgentLicenseNotAvailable', 47 => 'noBackupExecServersWithDeduplicationOptionLicenseAvailable', + 48 => 'no64BitBackupExecServersAvailableForExchangeResources', 49 => 'enterpriseVaultLicenseNotAvailable', + 50 => 'storageCannotBeVault', 51 => 'storageCannotBeStorageArray', 52 => 'invalidManagedBackupExecServer', + 53 => 'noIdleDevicesOnTargetBackupExecServerAvailable', 54 => 'noIdleDeviceInStoragePoolAvailable', + 55 => 'noCompatibleBackupExecServersAvailable', 56 => 'storageRequiresRestrictedSelection', + 57 => 'preferredBackupExecCatalogServerNotAvailable' +}; + +$job_type = { + 0 => 'unknown', 1 => 'backup', + 2 => 'restore', 3 => 'verify', + 4 => 'catalog', 5 => 'utility', + 6 => 'report', 7 => 'duplicate', + 8 => 'testRun', 9 => 'resourceDiscovery', + 10 => 'copyJob', 11 => 'install', + 12 => 'convertToVirtual', 13 => 'recoverVM', + 14 => 'removeVM', 15 => 'validateVM' +}; + +$storage_type = { + 0 => 'diskStorageDevicePool', 1 => 'tapeStorageDevicePool', + 2 => 'diskCartridgeStorageDevicePool', 3 => 'tapeDriveDevice', + 4 => 'diskStorageDevice', 5 => 'deduplicationDiskStorageDevice', + 6 => 'diskCartridgeDevice', 7 => 'roboticLibraryDevice', + 8 => 'roboticLibraryPartition', 9 => 'roboticLibrarySlot', + 10 => 'storageArrayDevice', 11 => 'virtualDiskDevice', + 12 => 'legacyBackupToDiskFolderDevice', 13 => 'cloudStorageDevice', + 14 => 'openStorageDevice', 15 => 'remoteMediaAgentForLinux', + 16 => 'ndmpServer' +}; + +$alert_severity = { + 0 => 'none', 1 => 'information', + 2 => 'question', 3 => 'warning', + 4 => 'error' +}; + +$alert_source = { + 0 => 'system', 1 => 'media', + 2 => 'device', 3 => 'job' +}; + +$alert_category = { + 0 => 'none', 1 => 'jobWarning', 2 => 'jobSuccess', + 3 => 'jobFailure', 4 => 'jobCancellation', 5 => 'catalogError', + 6 => 'softwareUpdateInformation', 7 => 'softwareUpdateWarning', + 8 => 'softwareUpdateError', 9 => 'installInformation', + 10 => 'installWarning', 11 => 'generalInformation', + 12 => 'databaseMaintenanceInformation', 13 => 'databaseMaintenanceFailure', + 14 => 'backupExecRetrieveUrlUpdateInformation', + 15 => 'backupExecRetrieveUrlUpdateFailure', 16 => 'idrCopyFailed', + 17 => 'idrFullBackupSuccess', 18 => 'backupJobContainsNoData', + 19 => 'jobCompletedWithExceptions', 20 => 'jobStart', + 21 => 'serviceStart', 22 => 'serviceStop', 23 => 'deviceError', + 24 => 'deviceWarning', 25 => 'deviceInformation', + 26 => 'deviceIntervention', 27 => 'mediaError', + 28 => 'mediaWarning', 29 => 'mediaInformation', + 30 => 'mediaIntervention', 31 => 'mediaInsert', + 32 => 'mediaOverwrite', 33 => 'mediaRemove', + 34 => 'libraryInsert', 35 => 'tapeAlertInformation', + 36 => 'tapeAlertWarning', 37 => 'tapeAlertError', + 38 => 'idrFullBackupSuccessWarning', 39 => 'licenseAndMaintenanceWarning' +}; + +1; diff --git a/centreon-plugins/apps/backup/backupexec/local/plugin.pm b/centreon-plugins/apps/backup/backupexec/local/plugin.pm new file mode 100644 index 000000000..b26cc3cba --- /dev/null +++ b/centreon-plugins/apps/backup/backupexec/local/plugin.pm @@ -0,0 +1,50 @@ +# +# 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::backupexec::local::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'alerts' => 'apps::backup::backupexec::local::mode::alerts', + 'disks' => 'apps::backup::backupexec::local::mode::disks', + 'jobs' => 'apps::backup::backupexec::local::mode::jobs', + 'list-disks' => 'apps::backup::backupexec::local::mode::listdisks' + }; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Backup Exec with powershell. + +=cut diff --git a/centreon-plugins/centreon/common/powershell/backupexec/alerts.pm b/centreon-plugins/centreon/common/powershell/backupexec/alerts.pm new file mode 100644 index 000000000..2d7d1f70b --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/backupexec/alerts.pm @@ -0,0 +1,82 @@ +# +# 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::backupexec::alerts; + +use strict; +use warnings; +use centreon::common::powershell::functions; +use centreon::common::powershell::backupexec::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::backupexec::functions::powershell_init(%options); + + $ps .= ' + +Try { + $ErrorActionPreference = "Stop" + + $items = New-Object System.Collections.Generic.List[Hashtable]; + Get-BEAlert | ForEach-Object { + $item = @{} + $item.name = $_.Name + $item.severity = $_.Severity.value__ + $item.source = $_.Source.value__ + $item.category = $_.Category.value__ + $item.message = $_.Message + $item.creationTime = (get-date -date $_.Date.ToUniversalTime() -Uformat ' . "'%s'" . ') + + $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 backup exec alerts. + +=cut diff --git a/centreon-plugins/centreon/common/powershell/backupexec/disks.pm b/centreon-plugins/centreon/common/powershell/backupexec/disks.pm new file mode 100644 index 000000000..ee61999c3 --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/backupexec/disks.pm @@ -0,0 +1,82 @@ +# +# 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::backupexec::disks; + +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::backupexec::functions::powershell_init(%options); + + $ps .= ' +Try { + $ErrorActionPreference = "Stop" + + $items = New-Object System.Collections.Generic.List[Hashtable]; + + Get-BEDiskStorageDevice | ForEach-Object { + $item = @{ + name = $_.Name; + disabled = $_.Disabled; + type = $_.StorageType.value__; + totalSpace = $_.TotalCapacityBytes; + usedSpace = $_.UsedCapacityBytes + } + + $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/backupexec/functions.pm b/centreon-plugins/centreon/common/powershell/backupexec/functions.pm new file mode 100644 index 000000000..1cf6f2f71 --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/backupexec/functions.pm @@ -0,0 +1,48 @@ +# +# 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::backupexec::functions; + +use strict; +use warnings; + +sub powershell_init { + my (%options) = @_; + + my $bemcli_file = defined($options{bemcli_file}) && $options{bemcli_file} ne '' ? + $options{bemcli_file} : 'C:/Program Files/Veritas/Backup Exec/Modules/BEMCLI/bemcli'; + my $ps = ' +If (@(Get-Module | Where-Object {$_.Name -Match "bemcli"} ).count -eq 0) { + Import-Module -Name "' . $bemcli_file . '" +} +'; + + return $ps; +} + +1; + +__END__ + +=head1 DESCRIPTION + +Powershell commands + +=cut diff --git a/centreon-plugins/centreon/common/powershell/backupexec/jobs.pm b/centreon-plugins/centreon/common/powershell/backupexec/jobs.pm new file mode 100644 index 000000000..3b858a1df --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/backupexec/jobs.pm @@ -0,0 +1,102 @@ +# +# 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::backupexec::jobs; + +use strict; +use warnings; +use centreon::common::powershell::functions; +use centreon::common::powershell::backupexec::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::backupexec::functions::powershell_init(%options); + + $ps .= ' + +Try { + $ErrorActionPreference = "Stop" + + $sessions = @{} + Get-BEJobHistory -FromLastJobRun | ForEach-Object { + $jobId = $_.JobId.toString() + $sessions[$jobId] = @{} + $sessions[$jobId].status = $_.JobStatus.value__ + $sessions[$jobId].creationTimeUTC = (get-date -date $_.StartTime.ToUniversalTime() -Uformat ' . "'%s'" . ') + $sessions[$jobId].endTimeUTC = (get-date -date $_.EndTime.ToUniversalTime() -Uformat ' . "'%s'" . ') + $sessions[$jobId].elapsedTime = $_.ElapsedTime.totalSeconds + } + + $items = New-Object System.Collections.Generic.List[Hashtable]; + Get-BEJob | ForEach-Object { + $item = @{} + $item.name = $_.Name + $item.type = $_.JobType.value__ + $item.isActive = $_.isActive + $item.status = $_.Status.value__ + $item.subStatus = $_.SubStatus.value__ + $item.creationTimeUTC = "" + $item.endTimeUTC = "" + $item.elapsedTime = 0 + + $id = $_.Id.toString() + if ($sessions.ContainsKey($id)) { + $item.status = $sessions[$id].status + $item.creationTimeUTC = $sessions[$id].creationTimeUTC + $item.endTimeUTC = $sessions[$id].endTimeUTC + $item.elapsedTime = $sessions[$id].elapsedTime + } + + $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 backup exec jobs. + +=cut