From 03ce23f9d728d4ecd4e4efd9cb081f9b3716302d Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Wed, 17 Jun 2020 16:46:50 +0200 Subject: [PATCH] migrate powershell with json --- .../hyperv/2012/local/mode/listnodevms.pm | 51 +++++- .../2012/local/mode/nodeintegrationservice.pm | 134 ++++++++------- .../hyperv/2012/local/mode/nodereplication.pm | 62 +++---- .../hyperv/2012/local/mode/nodesnapshot.pm | 71 ++++---- .../hyperv/2012/local/mode/nodevmstatus.pm | 58 ++++--- .../hyperv/2012/local/mode/resources/types.pm | 152 ++++++++++++++++++ .../local/mode/scvmmintegrationservice.pm | 122 ++++++++------ .../hyperv/2012/local/mode/scvmmsnapshot.pm | 58 ++++--- .../hyperv/2012/local/mode/scvmmvmstatus.pm | 72 +++++---- .../apps/sccm/local/mode/sitestatus.pm | 27 +--- .../apps/wsus/local/mode/computersstatus.pm | 29 ++-- .../apps/wsus/local/mode/serverstatistics.pm | 44 +++-- .../apps/wsus/local/mode/updatesstatus.pm | 31 ++-- .../centreon/common/powershell/functions.pm | 12 +- .../powershell/hyperv/2012/listnodevms.pm | 65 +++----- .../hyperv/2012/nodeintegrationservice.pm | 34 +++- .../powershell/hyperv/2012/nodereplication.pm | 18 ++- .../powershell/hyperv/2012/nodesnapshot.pm | 42 +++-- .../powershell/hyperv/2012/nodevmstatus.pm | 28 +++- .../hyperv/2012/scvmmintegrationservice.pm | 37 +++-- .../powershell/hyperv/2012/scvmmsnapshot.pm | 32 +++- .../powershell/hyperv/2012/scvmmvmstatus.pm | 20 ++- .../common/powershell/veeam/jobstatus.pm | 2 +- .../common/powershell/veeam/listjobs.pm | 2 +- .../common/powershell/veeam/tapejobs.pm | 2 +- .../common/powershell/windows/liststorages.pm | 2 +- 26 files changed, 788 insertions(+), 419 deletions(-) create mode 100644 centreon-plugins/apps/hyperv/2012/local/mode/resources/types.pm diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/listnodevms.pm b/centreon-plugins/apps/hyperv/2012/local/mode/listnodevms.pm index 95dfa119c..80e2a4cd4 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/listnodevms.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/listnodevms.pm @@ -26,6 +26,8 @@ use strict; use warnings; use centreon::plugins::misc; use centreon::common::powershell::hyperv::2012::listnodevms; +use apps::hyperv::2012::local::mode::resources::types qw($node_vm_state); +use JSON::XS; sub new { my ($class, %options) = @_; @@ -39,7 +41,7 @@ sub new { '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' }, + 'ps-display' => { name => 'ps_display' } }); return $self; @@ -50,6 +52,25 @@ sub check_options { $self->SUPER::init(%options); } +sub manage_selection { + my ($self, %options) = @_; + + #[ + # { "name": "XXXX1", "state": 2, "status": "Operating normally", "is_clustered": true, "note": null }, + # { "name": "XXXX2", "state": 2, "status": "Operating normally", "is_clustered": false, "note": null }, + # { "name": "XXXX3", "state": 2, "status": "Operating normally", "is_clustered": true, "note": null } + #] + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($options{stdout}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + return $decoded; +} + sub run { my ($self, %options) = @_; @@ -82,9 +103,20 @@ sub run { } else { $self->{output}->output_add( severity => 'OK', - short_msg => 'List Virtual Machines:' + short_msg => 'List virtual machines:' ); - centreon::common::powershell::hyperv::2012::listnodevms::list($self, stdout => $stdout); + + my $decoded = $self->manage_selection(stdout => $stdout); + foreach my $node (@$decoded) { + $self->{output}->output_add( + long_msg => sprintf( + "'%s' [state = %s] [status = %s]", + $node->{name}, + $node_vm_state->{ $node->{state} }, + $node->{status} + ) + ); + } } $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); @@ -112,7 +144,18 @@ sub disco_show { command_path => $self->{option_results}->{command_path}, command_options => $self->{option_results}->{command_options} ); - centreon::common::powershell::hyperv::2012::listnodevms::disco_show($self, stdout => $stdout); + + my $decoded = $self->manage_selection(stdout => $stdout); + + foreach my $node (@$decoded) { + $self->{output}->add_disco_entry( + name => $node->{name}, + state => $node_vm_state->{ $node->{state} }, + status => $node->{status}, + is_clustered => $node->{is_clustered} =~ /True|1/i ? 1 : 0, + note => defined($node->{note}) ? $node->{note} : '' + ); + } } 1; diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/nodeintegrationservice.pm b/centreon-plugins/apps/hyperv/2012/local/mode/nodeintegrationservice.pm index 8e04cf1c0..449546882 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/nodeintegrationservice.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/nodeintegrationservice.pm @@ -26,40 +26,20 @@ use strict; use warnings; use centreon::plugins::misc; use centreon::common::powershell::hyperv::2012::nodeintegrationservice; +use apps::hyperv::2012::local::mode::resources::types qw($node_vm_state $node_vm_integration_service_operational_status); use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use JSON::XS; sub custom_service_status_output { my ($self, %options) = @_; - my $msg = 'status : ' . $self->{result_values}->{primary_status} . '/' . $self->{result_values}->{secondary_status}; - return $msg; -} - -sub custom_service_status_calc { - my ($self, %options) = @_; - - $self->{result_values}->{primary_status} = $options{new_datas}->{$self->{instance} . '_primary_status'}; - $self->{result_values}->{secondary_status} = $options{new_datas}->{$self->{instance} . '_secondary_status'}; - $self->{result_values}->{vm} = $options{new_datas}->{$self->{instance} . '_vm'}; - $self->{result_values}->{service} = $options{new_datas}->{$self->{instance} . '_service'}; - return 0; + return 'status: ' . $self->{result_values}->{primary_status} . '/' . $self->{result_values}->{secondary_status}; } sub custom_global_status_output { my ($self, %options) = @_; - my $msg = 'state/version : ' . $self->{result_values}->{integration_service_state} . '/' . $self->{result_values}->{integration_service_version}; - return $msg; -} - -sub custom_global_status_calc { - my ($self, %options) = @_; - - $self->{result_values}->{integration_service_state} = $options{new_datas}->{$self->{instance} . '_integration_service_state'}; - $self->{result_values}->{integration_service_version} = $options{new_datas}->{$self->{instance} . '_integration_service_version'}; - $self->{result_values}->{vm} = $options{new_datas}->{$self->{instance} . '_vm'}; - $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; - return 0; + return 'state/version: ' . $self->{result_values}->{integration_service_state} . '/' . $self->{result_values}->{integration_service_version}; } sub set_counters { @@ -74,36 +54,34 @@ sub set_counters { $self->{maps_counters}->{global} = [ { label => 'global-status', threshold => 0, set => { key_values => [ { name => 'integration_service_state' }, { name => 'integration_service_version' }, { name => 'state' }, { name => 'vm' } ], - closure_custom_calc => $self->can('custom_global_status_calc'), closure_custom_output => $self->can('custom_global_status_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold } - }, + } ]; $self->{maps_counters}->{service} = [ { label => 'service-status', threshold => 0, set => { key_values => [ { name => 'primary_status' }, { name => 'secondary_status' }, { name => 'enabled' }, { name => 'vm' }, { name => 'service' } ], - closure_custom_calc => $self->can('custom_service_status_calc'), closure_custom_output => $self->can('custom_service_status_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold } - }, + } ]; } sub vm_long_output { my ($self, %options) = @_; - return "checking virtual machine '" . $options{instance_value}->{display} . "'"; + return "checking virtual machine '" . $options{instance_value}->{vm} . "'"; } sub prefix_vm_output { my ($self, %options) = @_; - return "VM '" . $options{instance_value}->{display} . "' "; + return "VM '" . $options{instance_value}->{vm} . "' "; } sub prefix_service_output { @@ -137,7 +115,7 @@ sub new { 'warning-global-status:s' => { name => 'warning_global_status', default => '%{integration_service_state} =~ /Update required/i' }, 'critical-global-status:s' => { name => 'critical_global_status', default => '' }, 'warning-service-status:s' => { name => 'warning_service_status', default => '' }, - 'critical-service-status:s' => { name => 'critical_service_status', default => '%{primary_status} !~ /Ok/i' }, + 'critical-service-status:s' => { name => 'critical_service_status', default => '%{primary_status} !~ /Ok/i' } }); return $self; @@ -182,48 +160,84 @@ sub manage_selection { $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } - - #[name= test1 ][state= Running ][IntegrationServicesState= Update required ][IntegrationServicesVersion= 3.1 ][note= ] - #[service= Time Synchronization ][enabled= True][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] - #[service= Heartbeat ][enabled= True][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] - #[service= Key-Value Pair Exchange ][enabled= True][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] - #[service= Shutdown ][enabled= True][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] - #[service= VSS ][enabled= True][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] - #[service= Guest Service Interface ][enabled= False][primaryOperationalStatus= Ok ][secondaryOperationalStatus= ] - #[name= test2 ][state= Running ][IntegrationServicesState= ][IntegrationServicesVersion= ][note= ] - #[service= Time Synchronization ][enabled= True][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] - #[service= Heartbeat ][enabled= True][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] - #[service= Key-Value Pair Exchange ][enabled= True][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] - #[service= Shutdown ][enabled= False][primaryOperationalStatus= NoContact ][secondaryOperationalStatus= ] + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + #[ + # { + # "name": "test1", "state": 2, "integration_services_state": "Update required", "integration_services_version": "3.1", "note": null, + # "services": [ + # { "service": "Time Synchronization", "enabled": true, "primary_operational_status": 12, "secondary_operational_status": null }, + # { "service": "Key-Value Pair Exchange", "enabled": true, "primary_operational_status": 12, "secondary_operational_status": null }, + # { "service": "Shutdown", "enabled": true, "primary_operational_status": 12, "secondary_operational_status": null }, + # { "service": "VSS", "enabled": true, "primary_operational_status": 12, "secondary_operational_status": null }, + # { "service": "Guest Service Interface", "enabled": false, "primary_operational_status": 2, "secondary_operational_status": null } + # ] + # }, + # { + # "name": "test2", "state": 2, "integration_services_state": null, "integration_services_version": null, "note": null, + # "services": [ + # { "service": "Time Synchronization", "enabled": true, "primary_operational_status": 12, "secondary_operational_status": null }, + # { "service": "Key-Value Pair Exchange", "enabled": true, "primary_operational_status": 12, "secondary_operational_status": null }, + # { "service": "Shutdown", "enabled": true, "primary_operational_status": 12, "secondary_operational_status": null }, + # { "service": "VSS", "enabled": true, "primary_operational_status": 12, "secondary_operational_status": null }, + # { "service": "Guest Service Interface", "enabled": false, "primary_operational_status": 2, "secondary_operational_status": null } + # ] + # } + #] $self->{vm} = {}; my $id = 1; - while ($stdout =~ /^\[name=\s*(.*?)\s*\]\[state=\s*(.*?)\s*\]\[IntegrationServicesState=\s*(.*?)\s*\]\[IntegrationServicesVersion=\s*(.*?)\s*\]\[note=\s*(.*?)\s*\](.*?)(?=\[name=|\z)/msig) { - my ($name, $status, $integration_service_state, $integration_service_version, $note, $content) = ($1, $2, $3, $4, $5, $6); - + foreach my $node (@$decoded) { if (defined($self->{option_results}->{filter_vm}) && $self->{option_results}->{filter_vm} ne '' && - $name !~ /$self->{option_results}->{filter_vm}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + $node->{name} !~ /$self->{option_results}->{filter_vm}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); next; } if (defined($self->{option_results}->{filter_status}) && $self->{option_results}->{filter_status} ne '' && - $status !~ /$self->{option_results}->{filter_status}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $status . "': no matching filter.", debug => 1); + $node_vm_state->{ $node->{state} } !~ /$self->{option_results}->{filter_status}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); next; } if (defined($self->{option_results}->{filter_note}) && $self->{option_results}->{filter_note} ne '' && - $note !~ /$self->{option_results}->{filter_note}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $note . "': no matching filter.", debug => 1); + defined($node->{note}) && $node->{note} !~ /$self->{option_results}->{filter_note}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); next; } - $self->{vm}->{$id} = { display => $name, vm => $name, service => {} }; - $self->{vm}->{$id}->{global} = { - $name => { vm => $name, integration_service_state => $integration_service_state, integration_service_version => $integration_service_version, state => $status } + $self->{vm}->{$id} = { + vm => $node->{name}, + service => {} }; + $self->{vm}->{$id}->{global} = { + $node->{name} => { + vm => $node->{name}, + integration_service_state => defined($node->{integration_services_state}) ? $node->{integration_services_state} : '-', + integration_service_version => defined($node->{integration_services_version}) ? $node->{integration_services_version} : '-', + state => $node_vm_state->{ $node->{state} } + } + }; + my $id2 = 1; - while ($content =~ /^\[service=\s*(.*?)\s*\]\[enabled=\s*(.*?)\s*\]\[primaryOperationalStatus=\s*(.*?)\s*\]\[secondaryOperationalStatus=\s*(.*?)\s*\]/msig) { - $self->{vm}->{$id}->{service}->{$id2} = { vm => $name, service => $1, enabled => $2, primary_status => $3, secondary_status => $4 }; + foreach my $service (@{$node->{services}}) { + $self->{vm}->{$id}->{service}->{$id2} = { + vm => $node->{name}, + service => $service->{service}, + enabled => $service->{enabled} =~ /True|1/i ? 1 : 0, + primary_status => + defined($service->{primary_operational_status}) && defined($node_vm_integration_service_operational_status->{ $service->{primary_operational_status} }) ? + $node_vm_integration_service_operational_status->{ $service->{primary_operational_status} } : '-', + secondary_status => + defined($service->{secondary_operational_status}) && defined($node_vm_integration_service_operational_status->{ $service->{secondary_operational_status} }) ? + $node_vm_integration_service_operational_status->{ $service->{secondary_operational_status} } : '-' + }; $id2++; } diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/nodereplication.pm b/centreon-plugins/apps/hyperv/2012/local/mode/nodereplication.pm index 089dd8fb5..d258470ce 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/nodereplication.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/nodereplication.pm @@ -26,45 +26,37 @@ use strict; use warnings; use centreon::plugins::misc; use centreon::common::powershell::hyperv::2012::nodereplication; +use apps::hyperv::2012::local::mode::resources::types qw($node_replication_state); use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use JSON::XS; sub custom_status_output { my ($self, %options) = @_; - - my $msg = 'replication health : ' . $self->{result_values}->{health}; - return $msg; -} -sub custom_status_calc { - my ($self, %options) = @_; - - $self->{result_values}->{vm} = $options{new_datas}->{$self->{instance} . '_vm'}; - $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; - $self->{result_values}->{health} = $options{new_datas}->{$self->{instance} . '_health'}; - return 0; + return 'replication health: ' . $self->{result_values}->{health}; } sub set_counters { my ($self, %options) = @_; - + $self->{maps_counters_type} = [ - { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All virtual machines are ok' }, + { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All virtual machines are ok' } ]; + $self->{maps_counters}->{vm} = [ { label => 'status', threshold => 0, set => { key_values => [ { name => 'vm' }, { name => 'state' }, { name => 'health' } ], - 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, + closure_custom_threshold_check => \&catalog_status_threshold } - }, + } ]; } sub prefix_vm_output { my ($self, %options) = @_; - + return "VM '" . $options{instance_value}->{vm} . "' "; } @@ -83,7 +75,7 @@ sub new { 'ps-display' => { name => 'ps_display' }, 'filter-vm:s' => { name => 'filter_vm' }, 'warning-status:s' => { name => 'warning_status', default => '%{health} =~ /Warning/i' }, - 'critical-status:s' => { name => 'critical_status', default => '%{health} =~ /Critical/i' }, + 'critical-status:s' => { name => 'critical_status', default => '%{health} =~ /Critical/i' } }); return $self; @@ -128,23 +120,35 @@ sub manage_selection { $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } - - #[name= XXXX1 ][state= Running ][health= Critical ] - #[name= XXXX2 ][state= Running ][health= Normal ] - #[name= XXXX3 ][state= Running ][health= Warning ] - $self->{vm} = {}; - - my $id = 1; - while ($stdout =~ /^\[name=\s*(.*?)\s*\]\[state=\s*(.*?)\s*\]\[health=\s*(.*?)\s*\].*?(?=\[name=|\z)/msig) { - my ($name, $status, $health) = ($1, $2, $3); + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + #[ + # { "name": "XXXX1", "state": "Replicating", "health": "Critical" }, + # { "name": "XXXX2", "state": "Replicating", "health": "Normal" }, + # { "name": "XXXX3", "state": "Replicating", "health": "Warning" } + #] + $self->{vm} = {}; + my $id = 1; + foreach my $node (@$decoded) { if (defined($self->{option_results}->{filter_vm}) && $self->{option_results}->{filter_vm} ne '' && $name !~ /$self->{option_results}->{filter_vm}/i) { $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); next; } - - $self->{vm}->{$id} = { display => $name, vm => $name, state => $status, health => $health }; + + $self->{vm}->{$id} = { + vm => $node->{name}, + state => $node_replication_state->{ $node->{state} }, + health => $node->{health} + }; $id++; } } diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/nodesnapshot.pm b/centreon-plugins/apps/hyperv/2012/local/mode/nodesnapshot.pm index 4192abb8c..d2b23be77 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/nodesnapshot.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/nodesnapshot.pm @@ -26,6 +26,8 @@ use strict; use warnings; use centreon::plugins::misc; use centreon::common::powershell::hyperv::2012::nodesnapshot; +use apps::hyperv::2012::local::mode::resources::types qw($node_vm_state); +use JSON::XS; sub set_counters { my ($self, %options) = @_; @@ -53,19 +55,19 @@ sub set_counters { sub custom_snapshot_output { my ($self, %options) = @_; - return "[status = " . $self->{result_values}->{status} . "] checkpoint started '" . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{snapshot}) . "' ago"; + return "checkpoint started " . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{snapshot}) . " ago"; } sub custom_backing_output { my ($self, %options) = @_; - return "[status = " . $self->{result_values}->{status} . "] backing started '" . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{backing}) . "' ago"; + return "backing started " . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{backing}) . " ago"; } sub prefix_vm_output { my ($self, %options) = @_; - - return "VM '" . $options{instance_value}->{display} . "' "; + + return "VM '" . $options{instance_value}->{display} . "' [status = " . $options{instance_value}->{status} . '] '; } sub new { @@ -112,7 +114,7 @@ sub manage_selection { 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', @@ -121,44 +123,59 @@ sub manage_selection { $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } - - #[name= ISC1-SV04404 ][state= Running ][note= ] - #[checkpointCreationTime= 1475502921.28734 ][type= snapshot] - #[checkpointCreationTime= 1475503073.81975 ][type= backing] + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + #[ + # { + # "name": "ISC1-SV04404", "state": 2, "note": null, + # "checkpoints": [ + # { "creation_time": 1475502921.28734, "type": "snapshot" }, + # { "creation_time": 1475503073.81975, "type": "backing" } + # ] + # } + #] $self->{vm} = {}; - + my ($id, $time) = (1, time()); - while ($stdout =~ /^\[name=\s*(.*?)\s*\]\[state=\s*(.*?)\s*\]\[note=\s*(.*?)\s*\](.*?)(?=\[name=|\z)/msig) { + foreach my $node (@$decoded) { my ($name, $status, $note, $content) = ($1, $2, $3, $4); - my %chkpt = (backing => -1, snapshot => -1); - while ($content =~ /\[checkpointCreationTime=\s*(.*?)\s*\]\[type=\s*(.*?)\s*\]/msig) { - my ($timestamp, $type) = ($1, $2); - $timestamp =~ s/,/\./g; - $chkpt{$type} = $timestamp if ($timestamp > 0 && ($chkpt{$type} == -1 || $chkpt{$type} > $timestamp)); + + my $checkpoint = { backing => -1, snapshot => -1 }; + foreach my $chkpt (@{$node->{checkpoints}}) { + $chkpt->{creation_time} =~ s/,/\./g; + $checkpoint->{ $chkpt->{type} } = $chkpt->{creation_time} if ($chkpt->{creation_time} > 0 && ($checkpoint->{ $chkpt->{type} } == -1 || $checkpoint->{ $chkpt->{type} } > $chkpt->{creation_time})); } - next if ($chkpt{backing} == -1 && $chkpt{snapshot} == -1); + next if ($checkpoint->{backing} == -1 && $checkpoint->{snapshot} == -1); if (defined($self->{option_results}->{filter_vm}) && $self->{option_results}->{filter_vm} ne '' && - $name !~ /$self->{option_results}->{filter_vm}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + $node->{name} !~ /$self->{option_results}->{filter_vm}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); next; } if (defined($self->{option_results}->{filter_note}) && $self->{option_results}->{filter_note} ne '' && - $note !~ /$self->{option_results}->{filter_note}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $note . "': no matching filter.", debug => 1); + defined($node->{note}) && $node->{note} !~ /$self->{option_results}->{filter_note}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); next; } if (defined($self->{option_results}->{filter_status}) && $self->{option_results}->{filter_status} ne '' && - $status !~ /$self->{option_results}->{filter_status}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $status . "': no matching filter.", debug => 1); + $node_vm_state->{ $node->{state} } !~ /$self->{option_results}->{filter_status}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); next; } $self->{vm}->{$id} = { - display => $name, - snapshot => $chkpt{snapshot} > 0 ? $time - $chkpt{snapshot} : undef, - backing => $chkpt{backing} > 0 ? $time - $chkpt{backing} : undef, - status => $status + display => $node->{name}, + snapshot => $checkpoint->{snapshot} > 0 ? $time - $checkpoint->{snapshot} : undef, + backing => $checkpoint->{backing} > 0 ? $time - $checkpoint->{backing} : undef, + status => $node_vm_state->{ $node->{state} } }; $id++; } diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/nodevmstatus.pm b/centreon-plugins/apps/hyperv/2012/local/mode/nodevmstatus.pm index 769c27dc8..1903dc5c0 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/nodevmstatus.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/nodevmstatus.pm @@ -27,22 +27,13 @@ use warnings; use centreon::plugins::misc; use centreon::common::powershell::hyperv::2012::nodevmstatus; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use apps::hyperv::2012::local::mode::resources::types qw($node_vm_state); +use JSON::XS; sub custom_status_output { my ($self, %options) = @_; - my $msg = 'status : ' . $self->{result_values}->{status} . " (state: " . $self->{result_values}->{state} . ", is clustered: " . $self->{result_values}->{is_clustered} . ")"; - return $msg; -} - -sub custom_status_calc { - my ($self, %options) = @_; - - $self->{result_values}->{vm} = $options{new_datas}->{$self->{instance} . '_vm'}; - $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; - $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; - $self->{result_values}->{is_clustered} = $options{new_datas}->{$self->{instance} . '_is_clustered'}; - return 0; + return 'status: ' . $self->{result_values}->{status} . " (state: " . $self->{result_values}->{state} . ", is clustered: " . $self->{result_values}->{is_clustered} . ")"; } sub set_counters { @@ -54,12 +45,11 @@ sub set_counters { $self->{maps_counters}->{vm} = [ { label => 'status', threshold => 0, set => { key_values => [ { name => 'vm' }, { name => 'state' }, { name => 'status' }, { name => 'is_clustered' } ], - 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, + closure_custom_threshold_check => \&catalog_status_threshold } - }, + } ]; } @@ -85,7 +75,7 @@ sub new { 'filter-vm:s' => { name => 'filter_vm' }, 'filter-note:s' => { name => 'filter_note' }, 'warning-status:s' => { name => 'warning_status', default => '' }, - 'critical-status:s' => { name => 'critical_status', default => '%{status} !~ /Operating normally/i' }, + 'critical-status:s' => { name => 'critical_status', default => '%{status} !~ /Operating normally/i' } }); return $self; @@ -130,28 +120,44 @@ sub manage_selection { $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } - - #[name= XXXX1 ][state= Running ][status= Operating normally ][IsClustered= True ][note= ] - #[name= XXXX2 ][state= Running ][status= Operating normally ][IsClustered= False ][note= ] - #[name= XXXX3 ][state= Running ][status= Operating normally ][IsClustered= False ][note= ] + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + #[ + # { "name": "XXXX1", "state": 2, "status": "Operating normally", "is_clustered": true, "note": null }, + # { "name": "XXXX2", "state": 2, "status": "Operating normally", "is_clustered": false, "note": null }, + # { "name": "XXXX3", "state": 2, "status": "Operating normally", "is_clustered": true, "note": null } + #] $self->{vm} = {}; my $id = 1; - while ($stdout =~ /^\[name=\s*(.*?)\s*\]\[state=\s*(.*?)\s*\]\[status=\s*(.*?)\s*\]\[IsClustered=\s*(.*?)\s*\]\[note=\s*(.*?)\s*\].*?(?=\[name=|\z)/msig) { + foreach my $node (@$decoded) { my ($name, $state, $status, $is_clustered, $note) = ($1, $2, $3, $4, $5); if (defined($self->{option_results}->{filter_vm}) && $self->{option_results}->{filter_vm} ne '' && - $name !~ /$self->{option_results}->{filter_vm}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + $node->{name} !~ /$self->{option_results}->{filter_vm}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); next; } if (defined($self->{option_results}->{filter_note}) && $self->{option_results}->{filter_note} ne '' && - $note !~ /$self->{option_results}->{filter_note}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $note . "': no matching filter.", debug => 1); + defined($node->{note}) && $node->{note} !~ /$self->{option_results}->{filter_note}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); next; } - $self->{vm}->{$id} = { display => $name, vm => $name, status => $status, state => $state, is_clustered => $is_clustered }; + $self->{vm}->{$id} = { + vm => $node->{name}, + status => $node->{status}, + state => $node_vm_state->{ $node->{state} }, + is_clustered => $node->{is_clustered} =~ /True|1/i ? 1 : 0 + }; $id++; } diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/resources/types.pm b/centreon-plugins/apps/hyperv/2012/local/mode/resources/types.pm new file mode 100644 index 000000000..c75a0b35c --- /dev/null +++ b/centreon-plugins/apps/hyperv/2012/local/mode/resources/types.pm @@ -0,0 +1,152 @@ +# +# Copyright 2020 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::hyperv::2012::local::mode::resources::types; + +use strict; +use warnings; +use Exporter; + +our $node_replication_state; +our $node_vm_integration_service_operational_status; +our $node_vm_state; +our $scvmm_vm_status; + +our @ISA = qw(Exporter); +our @EXPORT_OK = qw( + $node_replication_state $node_vm_integration_service_operational_status + $node_vm_state $scvmm_vm_status +); + +$node_vm_state = { + 1 => 'Other', + 2 => 'Running', + 3 => 'Off', + 4 => 'Stopping', + 6 => 'Saved', + 9 => 'Paused', + 10 => 'Starting', + 11 => 'Reset', + 32773 => 'Saving', + 32776 => 'Pausing', + 32777 => 'Resuming', + 32779 => 'FastSaved', + 32780 => 'FastSaving', + 32781 => 'ForceShutdown', + 32782 => 'ForceReboot', + 32783 => 'RunningCritical', + 32784 => 'OffCritical', + 32785 => 'StoppingCritical', + 32786 => 'SavedCritical', + 32787 => 'PausedCritical', + 32788 => 'StartingCritical', + 32789 => 'ResetCritical', + 32790 => 'SavingCritical', + 32791 => 'PausingCritical', + 32792 => 'ResumingCritical', + 32793 => 'FastSavedCritical', + 32794 => 'FastSavingCritical' +}; + +$node_replication_state = { + 0 => 'Disabled', + 1 => 'ReadyForInitialReplication', + 2 => 'InitialReplicationInProgress', + 3 => 'WaitingForInitialReplication', + 4 => 'Replicating', + 5 => 'PreparedForFailover', + 6 => 'FailedOverWaitingCompletion', + 7 => 'FailedOver', + 8 => 'Suspended', + 9 => 'Error', + 10 => 'WaitingForStartResynchronize', + 11 => 'Resynchronizing', + 12 => 'ResynchronizeSuspended', + 13 => 'RecoveryInProgress', + 14 => 'FailbackInProgress', + 15 => 'FailbackComplete', + 16 => 'WaitingForUpdateCompletion', + 17 => 'UpdateError', + 18 => 'WaitingForRepurposeCompletion', + 19 => 'PreparedForSyncReplication', + 20 => 'PreparedForGroupReverseReplication', + 21 => 'FiredrillInProgress' +}; + +$node_vm_integration_service_operational_status = { + 2 => 'Ok', + 3 => 'Degraded', + 6 => 'Error', + 7 => 'NonRecoverableError', + 12 => 'NoContact', + 13 => 'LostCommunication', + 32775 => 'ProtocolMismatch', + 32782 => 'ApplicationCritical', + 32783 => 'CommunicationTimedOut', + 32784 => 'CommunicationFailed', + 32896 => 'Disabled' +}; + +$scvmm_vm_status = { + 0 => 'Running', + 1 => 'PowerOff', + 2 => 'PoweringOff', + 3 => 'Saved', + 4 => 'Saving', + 5 => 'Restoring', + 6 => 'Paused', + 10 => 'DiscardSavedState', + 11 => 'Starting', + 12 => 'MergingDrives', + 13 => 'Deleting', + 14 => 'Reset', + 80 => 'DiscardingDrives', + 81 => 'Pausing', + 100 => 'UnderCreation', + 101 => 'CreationFailed', + 102 => 'Stored', + 103 => 'UnderTemplateCreation', + 104 => 'TemplateCreationFailed', + 105 => 'CustomizationFailed', + 106 => 'UnderUpdate', + 107 => 'UpdateFailed', + 108 => 'ReplacementFailed', + 109 => 'UnderReplacement', + 200 => 'UnderMigration', + 201 => 'MigrationFailed', + 210 => 'CreatingCheckpoint', + 211 => 'DeletingCheckpoint', + 212 => 'RecoveringCheckpoint', + 213 => 'CheckpointFailed', + 214 => 'InitializingCheckpointOperation', + 215 => 'FinishingCheckpointOperation', + 220 => 'Missing', + 221 => 'HostNotResponding', + 222 => 'Unsupported', + 223 => 'IncompleteVMConfig', + 224 => 'UnsupportedSharedFiles', + 225 => 'UnsupportedCluster', + 226 => 'UnderLiveCloning', + 227 => 'DbOnly', + 240 => 'P2VCreationFailed', + 250 => 'V2VCreationFailed' +}; + +1; diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm index 31aa2c858..294e4afd0 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm @@ -26,34 +26,34 @@ use strict; use warnings; use centreon::plugins::misc; use centreon::common::powershell::hyperv::2012::scvmmintegrationservice; +use apps::hyperv::2012::local::mode::resources::types qw($scvmm_vm_status); use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use JSON::XS; sub custom_status_output { my ($self, %options) = @_; - - my $msg = 'VMAddition : ' . $self->{result_values}->{vmaddition}; - return $msg; + + return 'VMAddition: ' . $self->{result_values}->{vmaddition}; } sub custom_status_calc { my ($self, %options) = @_; - + $self->{result_values}->{vm} = $options{new_datas}->{$self->{instance} . '_vm'}; $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; - $self->{result_values}->{vmaddition} = $options{new_datas}->{$self->{instance} . '_vmaddition'}; - $self->{result_values}->{operatingsystemshutdownenabled} = $options{new_datas}->{$self->{instance} . '_operatingsystemshutdownenabled'}; - $self->{result_values}->{timesynchronizationenabled} = $options{new_datas}->{$self->{instance} . '_timesynchronizationenabled'}; - $self->{result_values}->{dataexchangeenabled} = $options{new_datas}->{$self->{instance} . '_dataexchangeenabled'}; - $self->{result_values}->{heartbeatenabled} = $options{new_datas}->{$self->{instance} . '_heartbeatenabled'}; - $self->{result_values}->{backupenabled} = $options{new_datas}->{$self->{instance} . '_backupenabled'}; + $self->{result_values}->{vmaddition} = $options{new_datas}->{$self->{instance} . '_vm_addition'}; + $self->{result_values}->{operatingsystemshutdownenabled} = $options{new_datas}->{$self->{instance} . '_operating_system_shutdown_enabled'}; + $self->{result_values}->{timesynchronizationenabled} = $options{new_datas}->{$self->{instance} . '_time_synchronization_enabled'}; + $self->{result_values}->{dataexchangeenabled} = $options{new_datas}->{$self->{instance} . '_data_exchange_enabled'}; + $self->{result_values}->{heartbeatenabled} = $options{new_datas}->{$self->{instance} . '_heartbeat_enabled'}; + $self->{result_values}->{backupenabled} = $options{new_datas}->{$self->{instance} . '_backup_enabled'}; return 0; } sub custom_integrationservice_output { my ($self, %options) = @_; - my $msg = $self->{result_values}->{output_label} . ' : ' . $self->{result_values}->{service_status}; - return $msg; + return $self->{result_values}->{output_label} . ': ' . $self->{result_values}->{service_status}; } sub custom_integrationservice_calc { @@ -70,64 +70,65 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All integration services are ok' }, + { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All integration services are ok' } ]; + $self->{maps_counters}->{vm} = [ - { label => 'status', , threshold => 0, set => { - key_values => [ { name => 'vm' }, { name => 'status' }, { name => 'vmaddition' }, - { name => 'operatingsystemshutdownenabled' }, { name => 'timesynchronizationenabled' }, - { name => 'dataexchangeenabled' }, { name => 'heartbeatenabled' }, { name => 'backupenabled' } ], + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'vm' }, { name => 'status' }, { name => 'vm_addition' }, + { name => 'operating_system_shutdown_enabled' }, { name => 'time_synchronization_enabled' }, + { name => 'data_exchange_enabled' }, { name => 'heartbeat_enabled' }, { name => 'backup_enabled' } ], 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, + closure_custom_threshold_check => \&catalog_status_threshold } }, { label => 'osshutdown-status', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'operatingsystemshutdownenabled' } ], + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'operating_system_shutdown_enabled' } ], closure_custom_calc => $self->can('custom_integrationservice_calc'), - closure_custom_calc_extra_options => { output_label => 'Operating System Shutdown', name_status => 'operatingsystemshutdownenabled' }, + closure_custom_calc_extra_options => { output_label => 'operating system shutdown', name_status => 'operating_system_shutdown_enabled' }, closure_custom_output => $self->can('custom_integrationservice_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold } }, { label => 'timesync-status', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'timesynchronizationenabled' } ], + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'time_synchronization_enabled' } ], closure_custom_calc => $self->can('custom_integrationservice_calc'), - closure_custom_calc_extra_options => { output_label => 'Time Synchronization', name_status => 'timesynchronizationenabled' }, + closure_custom_calc_extra_options => { output_label => 'time synchronization', name_status => 'time_synchronization_enabled' }, closure_custom_output => $self->can('custom_integrationservice_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold } }, { label => 'dataexchange-status', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'dataexchangeenabled' } ], + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'data_exchange_enabled' } ], closure_custom_calc => $self->can('custom_integrationservice_calc'), - closure_custom_calc_extra_options => { output_label => 'Data Exchange', name_status => 'dataexchangeenabled' }, + closure_custom_calc_extra_options => { output_label => 'data exchange', name_status => 'data_exchange_enabled' }, closure_custom_output => $self->can('custom_integrationservice_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold } }, { label => 'heartbeat-status', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'heartbeatenabled' } ], + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'heartbeat_enabled' } ], closure_custom_calc => $self->can('custom_integrationservice_calc'), - closure_custom_calc_extra_options => { output_label => 'Heartbeat', name_status => 'heartbeatenabled' }, + closure_custom_calc_extra_options => { output_label => 'heartbeat', name_status => 'heartbeat_enabled' }, closure_custom_output => $self->can('custom_integrationservice_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold } }, { label => 'backup-status', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'backupenabled' } ], + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'backup_enabled' } ], closure_custom_calc => $self->can('custom_integrationservice_calc'), - closure_custom_calc_extra_options => { output_label => 'Backup', name_status => 'backupenabled' }, + closure_custom_calc_extra_options => { output_label => 'backup', name_status => 'backup_enabled' }, closure_custom_output => $self->can('custom_integrationservice_output'), closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold } - }, + } ]; } @@ -169,7 +170,7 @@ sub new { 'warning-heartbeat-status:s' => { name => 'warning_heartbeat_status', default => '' }, 'critical-heartbeat-status:s' => { name => 'critical_heartbeat_status', default => '' }, 'warning-backup-status:s' => { name => 'warning_backup_status', default => '' }, - 'critical-backup-status:s' => { name => 'critical_backup_status', default => '' }, + 'critical-backup-status:s' => { name => 'critical_backup_status', default => '' } }); return $self; @@ -186,7 +187,7 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Need to specify --" . $label_opt . " option."); $self->{output}->option_exit(); } - } + } $self->change_macros(macros => [ 'warning_status', 'critical_status', 'warning_osshutdown_status', 'critical_osshutdown_status', @@ -232,33 +233,54 @@ sub manage_selection { $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } - - #[VM= test1 ][Description= Test Descr - - pp - - aa ][Status= Running ][Cloud= ][HostGroup= All Hosts\CORP\test1 ][VMAddition= 6.3.9600.16384 ] - #[VM= test2 ][Description= ][Status= HostNotResponding ][Cloud= ][HostGroup= All Hosts\CORP\test2 ][VMAddition= Not Detected ] - #[VM= test3 ][Description= ][Status= HostNotResponding ][Cloud= ][HostGroup= All Hosts\CORP\test3 ][VMAddition= Not Detected ] - #[VM= test4 ][Description= ][Status= HostNotResponding ][Cloud= ][HostGroup= All Hosts\CORP\test4 ][VMAddition= Not Detected ] + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + #[ + # { "name": "test1", "description": "Test Descr - - pp - - aa", "status": 0, "cloud": "", "host_group_path": "All Hosts\\\CORP\\\test1", "vm_addition": "6.3.9600.16384" }, + # { + # "name": "test2", "description": "", "status": 0, "cloud": "", "host_group_path": "All Hosts\\\CORP\\\test2", "vm_addition": "Not Detected", + # "operating_system_shutdown_enabled": true, + # "time_synchronization_enabled": false, + # "data_exchange_enabled": true, + # "heartbeat_enabled": false, + # "backup_enabled": true + # } + #] $self->{vm} = {}; my $id = 1; - my @lines = split /\n/, $stdout; - foreach my $line (@lines) { - my %values; - while ($line =~ /\[(.*?)=\s*(.*?)\s*\]/g) { - $values{lc($1)} = $2; + foreach my $node (@$decoded) { + $node->{hostgroup} = $node->{host_group_path}; + $node->{vm} = $node->{name}; + $node->{status} = $scvmm_vm_status->{ $node->{status} }; + + foreach (('operating_system_shutdown_enabled', 'time_synchronization_enabled', 'data_exchange_enabled', 'heartbeat_enabled', 'backup_enabled')) { + $node->{$_} = ($node->{$_} =~ /True|1/i ? 1 : 0) if (defined($node->{$_})); } - $values{hostgroup} =~ s/\\/\//g; my $filtered = 0; foreach (('vm', 'description', 'status', 'hostgroup')) { if (defined($self->{option_results}->{'filter_' . $_}) && $self->{option_results}->{'filter_' . $_} ne '' && - $values{$_} !~ /$self->{option_results}->{'filter_' . $_}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $values{$_} . "': no matching filter.", debug => 1); + $node->{$_} !~ /$self->{option_results}->{'filter_' . $_}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); $filtered = 1; last; } } - $self->{vm}->{$id} = { %values } if ($filtered == 0); + next if ($filtered == 1); + + $self->{vm}->{$id} = { + %$node + }; $id++; } } diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmsnapshot.pm b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmsnapshot.pm index cd575a184..d422e4ad4 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmsnapshot.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmsnapshot.pm @@ -26,27 +26,29 @@ use strict; use warnings; use centreon::plugins::misc; use centreon::common::powershell::hyperv::2012::scvmmsnapshot; +use apps::hyperv::2012::local::mode::resources::types qw($scvmm_vm_status); +use JSON::XS; sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All VM snapshots are ok' }, + { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All VM snapshots are ok' } ]; $self->{maps_counters}->{vm} = [ { label => 'snapshot', set => { - key_values => [ { name => 'snapshot' }, { name => 'display' }], + key_values => [ { name => 'snapshot' }, { name => 'display' } ], closure_custom_output => $self->can('custom_vm_output'), - closure_custom_perfdata => sub { return 0; }, + closure_custom_perfdata => sub { return 0; } } - }, + } ]; } sub custom_vm_output { my ($self, %options) = @_; - return 'checkpoint started since : ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{snapshot}); + return 'checkpoint started since: ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{snapshot}); } sub prefix_vm_output { @@ -75,7 +77,7 @@ sub new { 'filter-vm:s' => { name => 'filter_vm' }, 'filter-description:s' => { name => 'filter_description' }, 'filter-hostgroup:s' => { name => 'filter_hostgroup' }, - 'filter-status:s' => { name => 'filter_status', default => 'running' }, + 'filter-status:s' => { name => 'filter_status', default => 'running' } }); return $self; @@ -133,34 +135,54 @@ sub manage_selection { $self->{output}->exit(); } - #[name= test-server ][description= ][status= Running ][cloud= ][hostgrouppath= All Hosts\CORP\Test\test-server ] - #[checkpointAddedTime= 1475502741.957 ] - #[checkpointAddedTime= 1475502963.21 ] + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + #[ + # { + # "name": "test-server", "description": "", "status": 0, "cloud": "", "host_group_path": "All Hosts\\\CORP\\\Test\\\test-server", + # "checkpoints": [ + # { "added_time": 1475502741.957 }, + # { "added_time": 1475502963.21 } + # ] + # } + #] $self->{vm} = {}; my $id = 1; - while ($stdout =~ /^\[name=\s*(.*?)\s*\]\[description=\s*(.*?)\s*\]\[status=\s*(.*?)\s*\]\[cloud=\s*(.*?)\s*\]\[hostgrouppath=\s*(.*?)\s*\](.*?)(?=\[name=|\z)/msig) { - my %values = (vm => $1, description => $2, status => $3, cloud => $4, hostgroup => $5); - my $content = $6; + foreach my $node (@$decoded) { + $node->{hostgroup} = $node->{host_group_path}; + $node->{vm} = $node->{name}; + $node->{status} = $scvmm_vm_status->{ $node->{status} }; my $chkpt = -1; - while ($content =~ /\[checkpointAddedTime=\s*(.*?)\s*\]/msig) { - $chkpt = $1 if ($chkpt == -1 || $chkpt > $1); + foreach (@{$node->{checkpoints}}) { + $chkpt = $_->{added_time} if ($chkpt == -1 || $chkpt > $_->{added_time}); } next if ($chkpt == -1); my $filtered = 0; - $values{hostgroup} =~ s/\\/\//g; foreach (('vm', 'description', 'status', 'hostgroup')) { if (defined($self->{option_results}->{'filter_' . $_}) && $self->{option_results}->{'filter_' . $_} ne '' && - $values{$_} !~ /$self->{option_results}->{'filter_' . $_}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $values{$_} . "': no matching filter.", debug => 1); + $node->{$_} !~ /$self->{option_results}->{'filter_' . $_}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{$_} . "': no matching filter.", debug => 1); $filtered = 1; last; } } - $self->{vm}->{$id} = { display => $values{vm}, snapshot => time() - $chkpt } if ($filtered == 0); + next if ($filtered == 1); + + $self->{vm}->{$id} = { + display => $node->{name}, + snapshot => time() - $chkpt + }; $id++; } } diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmvmstatus.pm b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmvmstatus.pm index 653d928fc..d51ddaf6d 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmvmstatus.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmvmstatus.pm @@ -26,38 +26,31 @@ use strict; use warnings; use centreon::plugins::misc; use centreon::common::powershell::hyperv::2012::scvmmvmstatus; +use apps::hyperv::2012::local::mode::resources::types qw($scvmm_vm_status); use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use JSON::XS; sub custom_status_output { my ($self, %options) = @_; - return 'status : ' . $self->{result_values}->{status}; -} - -sub custom_status_calc { - my ($self, %options) = @_; - - $self->{result_values}->{vm} = $options{new_datas}->{$self->{instance} . '_vm'}; - $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; - $self->{result_values}->{hostgroup} = $options{new_datas}->{$self->{instance} . '_hostgroup'}; - return 0; + return 'status: ' . $self->{result_values}->{status}; } sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All virtual machines are ok' }, + { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All virtual machines are ok' } ]; + $self->{maps_counters}->{vm} = [ { label => 'status', threshold => 0, set => { key_values => [ { name => 'vm' }, { name => 'hostgroup' }, { name => 'status' } ], - 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, + closure_custom_threshold_check => \&catalog_status_threshold } - }, + } ]; } @@ -88,7 +81,7 @@ sub new { 'filter-description:s' => { name => 'filter_description' }, 'filter-hostgroup:s' => { name => 'filter_hostgroup' }, 'warning-status:s' => { name => 'warning_status', default => '' }, - 'critical-status:s' => { name => 'critical_status', default => '%{status} !~ /Running|Stopped/i' }, + 'critical-status:s' => { name => 'critical_status', default => '%{status} !~ /Running|Stopped/i' } }); return $self; @@ -147,27 +140,44 @@ sub manage_selection { $self->{output}->exit(); } - #[name= test-server ][description= ][status= Running ][cloud= ][hostgrouppath= All Hosts\CORP\Test\test-server ] - #[name= test-server2 ][description= ][status= Running ][cloud= ][hostgrouppath= All Hosts\CORP\Test\test-server2 ] + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + #[ + # { "name": "test-server", "description": "", "status": 0, "cloud": "", "host_group_path": "All Hosts\\\CORP\\\Test\\\test-server" }, + # { "name": "test-server2", "description": "", "status": 0, "cloud": "", "host_group_path": "All Hosts\\\CORP\\\Test\\\test-server2" } + #] $self->{vm} = {}; my $id = 1; - while ($stdout =~ /^\[name=\s*(.*?)\s*\]\[description=\s*(.*?)\s*\]\[status=\s*(.*?)\s*\]\[cloud=\s*(.*?)\s*\]\[hostgrouppath=\s*(.*?)\s*\].*?(?=\[name=|\z)/msig) { - my %values = (vm => $1, description => $2, status => $3, cloud => $4, hostgroup => $5); - - my $filtered = 0; - $values{hostgroup} =~ s/\\/\//g; - foreach (('vm', 'description', 'hostgroup')) { - if (defined($self->{option_results}->{'filter_' . $_}) && $self->{option_results}->{'filter_' . $_} ne '' && - $values{$_} !~ /$self->{option_results}->{'filter_' . $_}/i) { - $self->{output}->output_add(long_msg => "skipping '" . $values{$_} . "': no matching filter.", debug => 1); - $filtered = 1; - last; - } + foreach my $node (@$decoded) { + if (defined($self->{option_results}->{filter_vm}) && $self->{option_results}->{filter_vm} ne '' && + $node->{name} !~ /$self->{option_results}->{filter_vm}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_description}) && $self->{option_results}->{filter_description} ne '' && + $node->{description} !~ /$self->{option_results}->{filter_description}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{node} . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_hostgroup}) && $self->{option_results}->{filter_hostgroup} ne '' && + $node->{host_group_path} !~ /$self->{option_results}->{filter_hostgroup}/i) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{node} . "': no matching filter.", debug => 1); + next; } - $self->{vm}->{$id} = { display => $values{vm}, vm => $values{vm}, status => $values{status}, hostgroup => $values{hostgroup} } - if ($filtered == 0); + $self->{vm}->{$id} = { + vm => $node->{name}, + status => $scvmm_vm_status->{ $node->{status} }, + hostgroup => $node->{host_group_path} + }; $id++; } diff --git a/centreon-plugins/apps/sccm/local/mode/sitestatus.pm b/centreon-plugins/apps/sccm/local/mode/sitestatus.pm index 8d9068800..b239e9f57 100644 --- a/centreon-plugins/apps/sccm/local/mode/sitestatus.pm +++ b/centreon-plugins/apps/sccm/local/mode/sitestatus.pm @@ -175,25 +175,14 @@ sub manage_selection { $self->{output}->option_exit(); } - if (ref($decoded) eq "ARRAY") { - foreach my $site (@{$decoded}) { - $self->{sites}->{$site->{SiteCode}} = { - display => $site->{SiteCode}, - SiteName => $site->{SiteName}, - Type => $map_type{$site->{Type}}, - Mode => $map_mode{$site->{Mode}}, - Status => $map_status{$site->{Status}}, - SecondarySiteCMUpdateStatus => $site->{SecondarySiteCMUpdateStatus}, - }; - } - } else { - $self->{sites}->{$decoded->{SiteCode}} = { - display => $decoded->{SiteCode}, - SiteName => $decoded->{SiteName}, - Type => $map_type{$decoded->{Type}}, - Mode => $map_mode{$decoded->{Mode}}, - Status => $map_status{$decoded->{Status}}, - SecondarySiteCMUpdateStatus => $decoded->{SecondarySiteCMUpdateStatus}, + foreach my $site (@{$decoded}) { + $self->{sites}->{$site->{SiteCode}} = { + display => $site->{SiteCode}, + SiteName => $site->{SiteName}, + Type => $map_type{$site->{Type}}, + Mode => $map_mode{$site->{Mode}}, + Status => $map_status{$site->{Status}}, + SecondarySiteCMUpdateStatus => $site->{SecondarySiteCMUpdateStatus} }; } diff --git a/centreon-plugins/apps/wsus/local/mode/computersstatus.pm b/centreon-plugins/apps/wsus/local/mode/computersstatus.pm index a02edd2f2..cb1443c2b 100644 --- a/centreon-plugins/apps/wsus/local/mode/computersstatus.pm +++ b/centreon-plugins/apps/wsus/local/mode/computersstatus.pm @@ -40,47 +40,42 @@ sub set_counters { key_values => [ { name => 'ComputersUpToDateCount' } ], output_template => 'Up-to-date: %d', perfdatas => [ - { label => 'computers_up_to_date', value => 'ComputersUpToDateCount', - template => '%d', min => 0 }, - ], + { label => 'computers_up_to_date', template => '%d', min => 0 } + ] } }, { label => 'needing-updates', set => { key_values => [ { name => 'ComputerTargetsNeedingUpdatesCount' } ], output_template => 'Needing Updates: %d', perfdatas => [ - { label => 'computers_needing_updates', value => 'ComputerTargetsNeedingUpdatesCount', - template => '%d', min => 0 }, - ], + { label => 'computers_needing_updates', template => '%d', min => 0 } + ] } }, { label => 'with-update-errors', set => { key_values => [ { name => 'ComputerTargetsWithUpdateErrorsCount' } ], output_template => 'With Update Errors: %d', perfdatas => [ - { label => 'computers_with_update_errors', value => 'ComputerTargetsWithUpdateErrorsCount', - template => '%d', min => 0 }, - ], + { label => 'computers_with_update_errors', template => '%d', min => 0 } + ] } }, { label => 'not-contacted', set => { key_values => [ { name => 'ComputersNotContactedSinceCount' } ], output_template => 'Not Contacted: %d', perfdatas => [ - { label => 'computers_not_contacted', value => 'ComputersNotContactedSinceCount', - template => '%d', min => 0 }, - ], + { label => 'computers_not_contacted', template => '%d', min => 0 } + ] } }, { label => 'unassigned', set => { key_values => [ { name => 'UnassignedComputersCount' } ], output_template => 'Unassigned: %s', perfdatas => [ - { label => 'computers_unassigned', value => 'UnassignedComputersCount', - template => '%d', min => 0 }, - ], + { label => 'computers_unassigned', template => '%d', min => 0 } + ] } - }, + } ]; } @@ -106,7 +101,7 @@ sub new { 'wsus-server:s' => { name => 'wsus_server', default => 'localhost' }, 'wsus-port:s' => { name => 'wsus_port', default => 8530 }, 'not-updated-since:s' => { name => 'not_updated_since', default => 10 }, - 'use-ssl' => { name => 'use_ssl' }, + 'use-ssl' => { name => 'use_ssl' } }); return $self; diff --git a/centreon-plugins/apps/wsus/local/mode/serverstatistics.pm b/centreon-plugins/apps/wsus/local/mode/serverstatistics.pm index d0c604395..4693df03a 100644 --- a/centreon-plugins/apps/wsus/local/mode/serverstatistics.pm +++ b/centreon-plugins/apps/wsus/local/mode/serverstatistics.pm @@ -40,74 +40,66 @@ sub set_counters { key_values => [ { name => 'ComputerTargetCount' } ], output_template => 'Computers: %d', perfdatas => [ - { label => 'computers', value => 'ComputerTargetCount', - template => '%d', min => 0 }, - ], + { label => 'computers', template => '%d', min => 0 } + ] } }, { label => 'computer-groups', set => { key_values => [ { name => 'CustomComputerTargetGroupCount' } ], output_template => 'Computer Groups: %d', perfdatas => [ - { label => 'computer_groups', value => 'CustomComputerTargetGroupCount', - template => '%d', min => 0 }, - ], + { label => 'computer_groups', template => '%d', min => 0 } + ] } }, { label => 'updates', set => { key_values => [ { name => 'UpdateCount' } ], output_template => 'Updates: %d', perfdatas => [ - { label => 'updates', value => 'UpdateCount', - template => '%d', min => 0 }, - ], + { label => 'updates', template => '%d', min => 0 } + ] } }, { label => 'approved-updates', set => { key_values => [ { name => 'ApprovedUpdateCount' } ], output_template => 'Approved Updates: %d', perfdatas => [ - { label => 'approved_updates', value => 'ApprovedUpdateCount', - template => '%d', min => 0 }, - ], + { label => 'approved_updates', template => '%d', min => 0 } + ] } }, { label => 'declined-updates', set => { key_values => [ { name => 'DeclinedUpdateCount' } ], output_template => 'Declined Updates: %d', perfdatas => [ - { label => 'declined_updates', value => 'DeclinedUpdateCount', - template => '%d', min => 0 }, - ], + { label => 'declined_updates', template => '%d', min => 0 } + ] } }, { label => 'not-approved-updates', set => { key_values => [ { name => 'NotApprovedUpdateCount' } ], output_template => 'Not Approved Updates: %d', perfdatas => [ - { label => 'not_approved_updates', value => 'NotApprovedUpdateCount', - template => '%d', min => 0 }, - ], + { label => 'not_approved_updates', template => '%d', min => 0 } + ] } }, { label => 'stale-updates', set => { key_values => [ { name => 'UpdatesWithStaleUpdateApprovalsCount' } ], output_template => 'Stale Updates: %d', perfdatas => [ - { label => 'stale_updates', value => 'UpdatesWithStaleUpdateApprovalsCount', - template => '%d', min => 0 }, - ], + { label => 'stale_updates', template => '%d', min => 0 } + ] } }, { label => 'expired-updates', set => { key_values => [ { name => 'ExpiredUpdateCount' } ], output_template => 'Expired Updates: %d', perfdatas => [ - { label => 'expired_updates', value => 'ExpiredUpdateCount', - template => '%d', min => 0 }, - ], + { label => 'expired_updates', template => '%d', min => 0 } + ] } - }, + } ]; } @@ -126,7 +118,7 @@ sub new { 'ps-display' => { name => 'ps_display' }, 'wsus-server:s' => { name => 'wsus_server', default => 'localhost' }, 'wsus-port:s' => { name => 'wsus_port', default => 8530 }, - 'use-ssl' => { name => 'use_ssl' }, + 'use-ssl' => { name => 'use_ssl' } }); return $self; diff --git a/centreon-plugins/apps/wsus/local/mode/updatesstatus.pm b/centreon-plugins/apps/wsus/local/mode/updatesstatus.pm index 52ebb502f..e36451f91 100644 --- a/centreon-plugins/apps/wsus/local/mode/updatesstatus.pm +++ b/centreon-plugins/apps/wsus/local/mode/updatesstatus.pm @@ -32,55 +32,50 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => 0, cb_prefix_output => 'prefix_output' }, + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' } ]; - + $self->{maps_counters}->{global} = [ { label => 'with-client-errors', set => { key_values => [ { name => 'UpdatesWithClientErrorsCount' } ], output_template => 'With Client Errors: %d', perfdatas => [ - { label => 'updates_with_client_errors', value => 'UpdatesWithClientErrorsCount', - template => '%d', min => 0 }, - ], + { label => 'updates_with_client_errors', template => '%d', min => 0 } + ] } }, { label => 'with-server-errors', set => { key_values => [ { name => 'UpdatesWithServerErrorsCount' } ], output_template => 'With Server Errors: %d', perfdatas => [ - { label => 'updates_with_server_errors', value => 'UpdatesWithServerErrorsCount', - template => '%d', min => 0 }, - ], + { label => 'updates_with_server_errors', template => '%d', min => 0 } + ] } }, { label => 'needing-files', set => { key_values => [ { name => 'UpdatesNeedingFilesCount' } ], output_template => 'Needing Files: %d', perfdatas => [ - { label => 'updates_needing_files_count', value => 'UpdatesNeedingFilesCount', - template => '%d', min => 0 }, - ], + { label => 'updates_needing_files_count', template => '%d', min => 0 } + ] } }, { label => 'needed-by-computers', set => { key_values => [ { name => 'UpdatesNeededByComputersCount' } ], output_template => 'Needed By Computers: %d', perfdatas => [ - { label => 'updates_needed_by_computers', value => 'UpdatesNeededByComputersCount', - template => '%d', min => 0 }, - ], + { label => 'updates_needed_by_computers', template => '%d', min => 0 } + ] } }, { label => 'up-to-date', set => { key_values => [ { name => 'UpdatesUpToDateCount' } ], output_template => 'Up-to-date: %s', perfdatas => [ - { label => 'updates_up_to_date', value => 'UpdatesUpToDateCount', - template => '%d', min => 0 }, - ], + { label => 'updates_up_to_date', template => '%d', min => 0 } + ] } - }, + } ]; } diff --git a/centreon-plugins/centreon/common/powershell/functions.pm b/centreon-plugins/centreon/common/powershell/functions.pm index 1e53ef170..de4157406 100644 --- a/centreon-plugins/centreon/common/powershell/functions.pm +++ b/centreon-plugins/centreon/common/powershell/functions.pm @@ -39,9 +39,9 @@ function Escape-JSONString($str) { sub convert_to_json { my (%options) = @_; - + my $ps = q{ -function ConvertTo-JSON-20($maxDepth = 4,$forceArray = $false) { +function ConvertTo-JSON-20($maxDepth = 4) { begin { $data = @() } @@ -49,12 +49,8 @@ function ConvertTo-JSON-20($maxDepth = 4,$forceArray = $false) { $data += $_ } - end{ - if ($data.length -eq 1 -and $forceArray -eq $false) { - $value = $data[0] - } else { - $value = $data - } + end{ + $value = $data if ($value -eq $null) { return "null" diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/listnodevms.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/listnodevms.pm index acda49bc5..ddcf59018 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/listnodevms.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/listnodevms.pm @@ -22,7 +22,7 @@ package centreon::common::powershell::hyperv::2012::listnodevms; use strict; use warnings; -use centreon::plugins::misc; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -30,17 +30,35 @@ sub get_powershell { my $ps = ' $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 .= ' $ProgressPreference = "SilentlyContinue" Try { $ErrorActionPreference = "Stop" $vms = Get-VM + $items = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($vm in $vms) { + $item = @{} + $note = $vm.Notes -replace "\r","" $note = $note -replace "\n"," - " - Write-Host "[name=" $vm.VMName "][state=" $vm.State "][status=" $vm.Status "][IsClustered=" $vm.IsClustered "][note=" $note "]" + $item.name = $vm.VMName + $item.state = $vm.State.value__ + $item.status = $vm.Status + $item.note = $note + $item.is_clustered = $vm.IsClustered + + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 @@ -52,49 +70,6 @@ exit 0 return $ps; } - -sub list { - my ($self, %options) = @_; - - # Following output: - #[name= XXXX1 ][state= Running ][status= Operating normally ][IsClustered= True ][note= ] - #... - - foreach my $line (split /\n/, $options{stdout}) { - next if ($line !~ /^\[name=(.*?)\]\[state=(.*?)\]\[status=(.*?)\]\[IsClustered=(.*?)\]\[note=(.*?)\]/); - my ($name, $state, $status, $IsClustered, $note) = ( - centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2), - centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5) - ); - - $self->{output}->output_add(long_msg => "'" . $name . "' [state = $state, status = " . $status . ']'); - } -} - -sub disco_show { - my ($self, %options) = @_; - - # Following output: - #[name= XXXX1 ][state= Running ][status= Operating normally ][IsClustered= True ][note= ] - #... - - foreach my $line (split /\n/, $options{stdout}) { - next if ($line !~ /^\[name=(.*?)\]\[state=(.*?)\]\[status=(.*?)\]\[IsClustered=(.*?)\]\[note=(.*?)\]/); - my ($name, $state, $status, $IsClustered, $note) = ( - centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2), - centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5) - ); - - $self->{output}->add_disco_entry( - name => $name, - state => $state, - status => $status, - is_clustered => $IsClustered, - note => $note - ); - } -} - 1; __END__ diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodeintegrationservice.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodeintegrationservice.pm index 08c0922f1..e12393cf9 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodeintegrationservice.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodeintegrationservice.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::hyperv::2012::nodeintegrationservice; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,20 +30,49 @@ sub get_powershell { my $ps = ' $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 .= ' $ProgressPreference = "SilentlyContinue" Try { $ErrorActionPreference = "Stop" $vms = Get-VM + + $items = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($vm in $vms) { + $item = @{} + $note = $vm.Notes -replace "\r","" $note = $note -replace "\n"," - " - Write-Host "[name=" $vm.VMName "][state=" $vm.State "][IntegrationServicesState=" $vm.IntegrationServicesState "][IntegrationServicesVersion=" $vm.IntegrationServicesVersion "][note=" $note "]" + + $item.name = $vm.VMName + $item.state = $vm.State.value__ + $item.integration_services_state = $vm.IntegrationServicesState + $item.integration_services_version = $vm.IntegrationServicesVersion + $item.note = $note + + $services = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($service in $VM.VMIntegrationService) { - Write-Host "[service=" $service.Name "][enabled=" $service.Enabled "][primaryOperationalStatus=" $service.PrimaryOperationalStatus "][secondaryOperationalStatus=" $service.SecondaryOperationalStatus "]" + $service = @{} + + $service.name = $service.Name + $service.enabled = $service.Enabled + $service.primary_operational_status = $service.PrimaryOperationalStatus.value__ + $service.secondary_operational_status = $service.SecondaryOperationalStatus.value__ + $services.Add($service) } + + $item.services = $services + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodereplication.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodereplication.pm index d9592a1a6..9ecb74f49 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodereplication.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodereplication.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::hyperv::2012::nodereplication; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,15 +30,30 @@ sub get_powershell { my $ps = ' $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 .= ' $ProgressPreference = "SilentlyContinue" Try { $ErrorActionPreference = "Stop" $vms = Get-VMReplication + $items = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($vm in $vms) { - Write-Host "[name=" $vm.Name "][state=" $vm.State "][health=" $vm.Health "]" + $item = @{} + + $item.name = $vm.Name + $item.state = $vm.State.value__ + $item.health = $vm.Health.value__ + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodesnapshot.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodesnapshot.pm index dcbf11273..5ef945154 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodesnapshot.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodesnapshot.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::hyperv::2012::nodesnapshot; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,6 +30,12 @@ sub get_powershell { my $ps = ' $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 .= ' $ProgressPreference = "SilentlyContinue" Try { @@ -37,18 +44,24 @@ Try { if ($vms.Length -gt 0) { $snapshots = Get-VMSnapshot -VMName * } - + + $items = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($vm in $vms) { - $i=0 + $item = @{} + $note = $vm.Notes -replace "\r","" $note = $note -replace "\n"," - " + $item.note = $note + $item.name = $vm.VMName + $item.state = $vm.State.value__ + + $checkpoints = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($snap in $snapshots) { if ($snap.VMName -eq $vm.VMName) { - if ($i -eq 0) { - Write-Host "[name=" $vm.VMName "][state=" $vm.State "][note=" $note "]" - } - Write-Host "[checkpointCreationTime=" (get-date -date $snap.CreationTime.ToUniversalTime() -UFormat ' . "'%s'" . ') "][type= snapshot]" - $i=1 + $checkpoint = @{} + $checkpoint.type = "snapshot" + $checkpoint.creation_time = (get-date -date $snap.CreationTime.ToUniversalTime() -UFormat ' . "'%s'" . ') + $checkpoints.Add($checkpoint) } } if ($vm.status -imatch "Backing") { @@ -56,16 +69,21 @@ Try { Foreach ($VMDisk in $VMDisks) { $VHD = Get-VHD $VMDisk.Path if ($VHD.Path -imatch ".avhdx" -or $VHD.VhdType -imatch "Differencing") { + $checkpoint = @{} $parent = Get-Item $VHD.ParentPath - if ($i -eq 0) { - Write-Host "[name=" $vm.VMName "][state=" $vm.State "][note=" $note "]" - } - Write-Host "[checkpointCreationTime=" (get-date -date $parent.LastWriteTime.ToUniversalTime() -UFormat ' . "'%s'" . ') "][type= backing]" - $i=1 + $checkpoint.type = "backing" + $checkpoint.creation_time = (get-date -date $parent.LastWriteTime.ToUniversalTime() -UFormat ' . "'%s'" . ') + $checkpoints.Add($checkpoint) } } } + + $item.checkpoints = $checkpoints + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodevmstatus.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodevmstatus.pm index 1aa780ba3..34d3097be 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodevmstatus.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodevmstatus.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::hyperv::2012::nodevmstatus; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,6 +30,12 @@ sub get_powershell { my $ps = ' $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 .= ' $ProgressPreference = "SilentlyContinue" Try { @@ -41,16 +48,29 @@ Try { $node_is_clustered = 1 } } Catch { - } + } + + $items = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($vm in $vms) { + $item = @{} + $note = $vm.Notes -replace "\r","" $note = $note -replace "\n"," - " - $isClustered = $vm.IsClustered + + $item.name = $vm.VMName + $item.state = $vm.State.value__ + $item.status = $vm.Status + $item.note = $note + $item.is_clustered = $vm.IsClustered if ($node_is_clustered -eq 0) { - $isClustered = "nodeNotClustered" + $item.is_clustered = $false } - Write-Host "[name=" $vm.VMName "][state=" $vm.State "][status=" $vm.Status "][IsClustered=" $isClustered "][note=" $note "]" + + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmintegrationservice.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmintegrationservice.pm index ca4d72fbb..e7769810e 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmintegrationservice.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmintegrationservice.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::hyperv::2012::scvmmintegrationservice; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,6 +30,12 @@ sub get_powershell { my $ps = ' $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 .= ' $ProgressPreference = "SilentlyContinue" Try { @@ -42,21 +49,29 @@ Try { $connection = Get-VMMServer -ComputerName "' . $options{scvmm_hostname} . '" -TCPPort ' . $options{scvmm_port} . ' -Credential $UserCredential $vms = Get-SCVirtualMachine -VMMServer $connection + $items = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($vm in $vms) { + $item = @{} + $desc = $vm.description -replace "\r","" $desc = $desc -replace "\n"," - " - Write-Host ("[VM={0}]" -f $vm.Name) -NoNewline - Write-Host ("[Description={0}]" -f $desc) -NoNewline - Write-Host ("[Status={0}]" -f $vm.Status) -NoNewline - Write-Host ("[Cloud={0}]" -f $vm.Cloud) -NoNewline - Write-Host ("[HostGroup={0}]" -f $vm.HostGroupPath) -NoNewline - Write-Host ("[VMAddition={0}]" -f $vm.VMAddition) -NoNewline - Write-Host ("[OperatingSystemShutdownEnabled={0}]" -f $vm.OperatingSystemShutdownEnabled) -NoNewline - Write-Host ("[TimeSynchronizationEnabled={0}]" -f $vm.TimeSynchronizationEnabled) -NoNewline - Write-Host ("[DataExchangeEnabled={0}]" -f $vm.DataExchangeEnabled) -NoNewline - Write-Host ("[HeartbeatEnabled={0}]" -f $vm.HeartbeatEnabled) -NoNewline - Write-Host ("[BackupEnabled={0}]" -f $vm.BackupEnabled) + $item.name = $vm.Name + $item.status = $vm.Status.value__ + $item.description = $desc + $item.cloud = $vm.Cloud + $item.host_group_path = $vm.HostGroupPath + $item.vm_addition = $vm.VMAddition + $item.operating_system_shutdown_enabled = $vm.OperatingSystemShutdownEnabled + $item.time_synchronization_enabled = $vm.TimeSynchronizationEnabled + $item.data_exchange_enabled = $vm.DataExchangeEnabled + $item.heartbeat_enabled = $vm.HeartbeatEnabled + $item.backup_enabled = $vm.BackupEnabled + + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmsnapshot.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmsnapshot.pm index d91ae71ef..ce96c0412 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmsnapshot.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmsnapshot.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::hyperv::2012::scvmmsnapshot; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,6 +30,12 @@ sub get_powershell { my $ps = ' $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 .= ' $ProgressPreference = "SilentlyContinue" Try { @@ -42,19 +49,32 @@ Try { $connection = Get-VMMServer -ComputerName "' . $options{scvmm_hostname} . '" -TCPPort ' . $options{scvmm_port} . ' -Credential $UserCredential $vms = Get-SCVirtualMachine -VMMServer $connection + $items = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($vm in $vms) { - $i = 0 + $item = @{} + $checkpoints = Get-SCVMCheckpoint -VMMServer $connection -Vm $vm $desc = $vm.description -replace "\r","" $desc = $desc -replace "\n"," - " + $item.name = $vm.Name + $item.description = $desc + $item.status = $vm.Status.value__ + $item.host_group_path = $vm.HostGroupPath + + $chkpt_list = New-Object System.Collections.Generic.List[Hashtable]; foreach ($checkpoint in $checkpoints) { - if ($i -eq 0) { - Write-Host "[name=" $vm.Name "][description=" $desc "][status=" $vm.Status "][cloud=" $vm.Cloud "][hostgrouppath=" $vm.HostGroupPath "]" - } - Write-Host "[checkpointAddedTime=" (get-date -date $checkpoint.AddedTime.ToUniversalTime() -UFormat ' . "'%s'" . ') "]" - $i = 1 + $chkpt = @{} + $chkpt.type = "backing" + $chkpt.added_time = (get-date -date $checkpoint.AddedTime.ToUniversalTime() -UFormat ' . "'%s'" . ') + $chkpt_list.Add($chkpt) } + + $item.checkpoints = $chkpt_list + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmvmstatus.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmvmstatus.pm index 8f90fe66f..a9f93c4fd 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmvmstatus.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/scvmmvmstatus.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::hyperv::2012::scvmmvmstatus; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,6 +30,12 @@ sub get_powershell { my $ps = ' $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 .= ' $ProgressPreference = "SilentlyContinue" Try { @@ -42,11 +49,22 @@ Try { $connection = Get-VMMServer -ComputerName "' . $options{scvmm_hostname} . '" -TCPPort ' . $options{scvmm_port} . ' -Credential $UserCredential $vms = Get-SCVirtualMachine -VMMServer $connection + $items = New-Object System.Collections.Generic.List[Hashtable]; Foreach ($vm in $vms) { + $item = @{} + $desc = $vm.description -replace "\r","" $desc = $desc -replace "\n"," - " - Write-Host "[name=" $vm.Name "][description=" $desc "][status=" $vm.Status "][cloud=" $vm.Cloud "][hostgrouppath=" $vm.HostGroupPath "]" + $item.name = $vm.Name + $item.description = $desc + $item.status = $vm.Status.value__ + $item.cloud = $vm.Cloud + $item.host_group_path = $vm.HostGroupPath + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm b/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm index 42d9afd4b..4cd903387 100644 --- a/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm +++ b/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm @@ -77,7 +77,7 @@ Try { $items.Add($item) } - $jsonString = $items | ConvertTo-JSON-20 -forceArray 1 + $jsonString = $items | ConvertTo-JSON-20 Write-Host $jsonString } Catch { Write-Host $Error[0].Exception diff --git a/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm b/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm index 46badedaf..a2fa0799e 100644 --- a/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm +++ b/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm @@ -67,7 +67,7 @@ Try { $items.Add($item) } - $jsonString = $items | ConvertTo-JSON-20 -forceArray 1 + $jsonString = $items | ConvertTo-JSON-20 Write-Host $jsonString } Catch { Write-Host $Error[0].Exception diff --git a/centreon-plugins/centreon/common/powershell/veeam/tapejobs.pm b/centreon-plugins/centreon/common/powershell/veeam/tapejobs.pm index 578b9f2bc..9d1d9e03a 100644 --- a/centreon-plugins/centreon/common/powershell/veeam/tapejobs.pm +++ b/centreon-plugins/centreon/common/powershell/veeam/tapejobs.pm @@ -70,7 +70,7 @@ Try { $items.Add($item) } - $jsonString = $items | ConvertTo-JSON-20 -forceArray 1 + $jsonString = $items | ConvertTo-JSON-20 Write-Host $jsonString } Catch { Write-Host $Error[0].Exception diff --git a/centreon-plugins/centreon/common/powershell/windows/liststorages.pm b/centreon-plugins/centreon/common/powershell/windows/liststorages.pm index 981fd4daf..b02a217f7 100644 --- a/centreon-plugins/centreon/common/powershell/windows/liststorages.pm +++ b/centreon-plugins/centreon/common/powershell/windows/liststorages.pm @@ -57,7 +57,7 @@ Try { $items.Add($item) } - $jsonString = $items | ConvertTo-JSON-20 -forceArray 1 + $jsonString = $items | ConvertTo-JSON-20 Write-Host $jsonString } Catch { Write-Host $Error[0].Exception