feat(apps::vmware::vsphere8::vm): new plugin (#5747)

Co-authored-by: Evan-Adam <152897682+Evan-Adam@users.noreply.github.com>
Co-authored-by: Sylvain Cresto <scresto@centreon.com>

Refs: CTOR-432
This commit is contained in:
omercier 2025-09-12 17:25:10 +02:00 committed by GitHub
parent 7ee422e924
commit d60651f5af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 3365 additions and 4 deletions

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"libjson-perl"
]
}

View File

@ -0,0 +1,10 @@
{
"pkg_name": "centreon-plugin-Virtualization-Vmware8-Vm-Restapi",
"pkg_summary": "Centreon Plugin to monitor VMware virtual machines using vSphere 8 REST API",
"plugin_name": "centreon_vmware8_vm_restapi.pl",
"files": [
"centreon/plugins/script_custom.pm",
"apps/vmware/vsphere8/vm/",
"apps/vmware/vsphere8/custom/"
]
}

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"perl(JSON)"
]
}

View File

@ -202,8 +202,16 @@ sub try_request_api {
$self->{output}->option_exit();
}
return {} if ($method ne 'GET');
my $decoded = ($method eq 'GET') ? centreon::plugins::misc::json_decode($content, booleans_as_strings => 1) : {};
my $decoded = centreon::plugins::misc::json_decode($content, booleans_as_strings => 1);
if (!defined($decoded)) {
$self->{output}->add_option_msg(short_msg => "API returns empty/invalid content [code: '"
. $self->{http}->get_code() . "'] [message: '"
. $self->{http}->get_message() . "'] [content: '"
. $content . "']");
$self->{output}->option_exit();
}
return $decoded;
}
@ -224,8 +232,8 @@ sub request_api {
$api_response = $self->try_request_api('force_authentication' => 1, %options);
}
# if we could not authenticate, we exit
if (ref($api_response) eq 'HASH' && defined($api_response->{error_type})) {
# if we could not authenticate, we exit (unless no_fail option is true)
if (ref($api_response) eq 'HASH' && defined($api_response->{error_type}) && ! $options{no_fail}) {
my $full_message = '';
for my $error_item (@{$api_response->{messages}}) {
$full_message .= '[Id: ' . $error_item->{id} . ' - Msg: ' . $error_item->{default_message} . ' (' . join(', ', @{$error_item->{args}}) . ')]';
@ -236,6 +244,28 @@ sub request_api {
return $api_response;
}
sub get_folder_ids_by_names {
my ($self, %options) = @_;
my $api_response = $self->request_api(
%options,
'endpoint' => '/vcenter/folder?names=' . $options{names},
'method' => 'GET');
my @folders = map { $_->{folder} } @{$api_response};
return join(',', @folders);
}
sub get_vm_guest_identity {
my ($self, %options) = @_;
my $api_response = $self->request_api(
'endpoint' => '/vcenter/vm/' . $options{vm_id} . '/guest/identity',
'method' => 'GET',
no_fail => 1);
return $api_response;
}
sub get_all_acq_specs {
my ($self, %options) = @_;
@ -408,10 +438,26 @@ sub get_stats {
endpoint => $endpoint
);
if (defined($result->{messages})) {
# Example of what can happen when a VM has no stats
# {
# "messages": [
# {
# "args": [],
# "default_message": "Invalid data points filter: found empty set of Resource Addresses for provided set of (types,resources)",
# "localized": "Invalid data points filter: found empty set of Resource Addresses for provided set of (types,resources)",
# "id": "com.vmware.vstats.data_points_invalid_resource_filter"
# }
# ]
# }
$self->{output}->add_option_msg(short_msg => "No stats found. Error: " . $result->{messages}->[0]->{default_message});
$self->{output}->option_exit();
}
# FIXME: check if ( !defined($result) || ref($result) ne 'HASH' || scalar(@{ $result->{data_points} }) == 0 ) {
# FIXME: the existence of the resource id must be checked at one moment
# return only the last value (if there are several)
if ( scalar(@{ $result->{data_points} }) == 0 ) {
if ( !defined($result->{data_points}) || scalar(@{ $result->{data_points} }) == 0 ) {
$self->{output}->add_option_msg(short_msg => "no data for host " . $options{rsrc_id} . " counter " . $options{cid} . " at the moment.");
return undef;
}
@ -562,6 +608,50 @@ Calls try_request_api and recalls it forcing authentication if the first call fa
=back
=head2 get_folder_ids_by_names
my $folder_ids = $self->get_folder_ids_by_names(names => $folder_names);
Retrieves the IDs of folders based on their names.
=over 4
=item * C<%options> - A hash of options. The following keys are supported:
=over 8
=item * C<names> - A comma-separated string of folder names to search for. This option is required.
=back
=back
Returns a comma-separated string of folder IDs corresponding to the provided folder names.
=cut
=head2 get_vm_guest_identity
my $identity = $self->get_vm_guest_identity(vm_id => $vm_id);
Retrieves the guest identity information for a specific virtual machine (VM) using its ID.
=over 4
=item * C<%options> - A hash of options. The following keys are supported:
=over 8
=item * C<vm_id> - The ID of the virtual machine for which to retrieve the guest identity. This option is required.
=back
=back
Returns the guest identity information as a hash reference if successful, or undef if the request fails.
=cut
=head2 get_acq_spec
my $spec = $self->get_acq_spec(%options);

View File

@ -0,0 +1,240 @@
#
# Copyright 2025 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::vmware::vsphere8::vm::mode;
use strict;
use warnings;
use base qw(centreon::plugins::templates::counter);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
$options{options}->add_options(
arguments => {
'vm-id:s' => { name => 'vm_id' },
'vm-name:s' => { name => 'vm_name' }
}
);
$options{options}->add_help(package => __PACKAGE__, sections => 'VMWARE 8 VM OPTIONS', once => 1);
return $self;
}
sub get_vm_id_from_name {
my ($self, %options) = @_;
if ( centreon::plugins::misc::is_empty($self->{vm_name}) ) {
$self->{output}->add_option_msg(short_msg => "get_vm_id_from_name method called without vm_name option. Please check configuration.");
$self->{output}->option_exit();
}
my $response = $options{custom}->request_api(
'endpoint' => '/vcenter/vm',
'get_param' => [ 'names='. $self->{vm_name} ],
'method' => 'GET'
);
for my $rsrc (@$response) {
next if ($rsrc->{name} ne $self->{vm_name});
$self->{vm_id} = $rsrc->{vm};
$self->{output}->add_option_msg(long_msg => "get_vm_id_from_name method called to get " . $self->{vm_name}
. "'s id: " . $self->{vm_id} . ". Prefer using --vm-id to spare a query to the API.");
return $rsrc->{vm};
}
return undef;
}
sub get_vm {
my ($self, %options) = @_;
my $vm;
# if the VM's ID was given in the parameters, use it to get all the data of the VM
if (!centreon::plugins::misc::is_empty($self->{vm_id})) {
my $response = $self->request_api(
%options,
'endpoint' => '/vcenter/vm/' . $self->{vm_id},
'method' => 'GET',
'no_fail' => 1
);
$vm = $response;
}
# if the VM's ID was not provided or if the first query did not succeed, we look for the vm by its name
if (centreon::plugins::misc::is_empty($vm->{name}) && !centreon::plugins::misc::is_empty($self->{vm_name})) {
my $response = $self->request_api(
%options,
'endpoint' => '/vcenter/vm',
'get_param' => [ 'names='. $self->{vm_name} ],
'method' => 'GET'
);
$vm = $response->[0] // undef;
}
if (centreon::plugins::misc::is_empty($vm->{name})) {
$self->{output}->add_option_msg(short_msg => "No VM found.");
$self->{output}->option_exit();
}
# the VM's ID (vm-xxxx) is not returned if the vm was obtained by it's vm_id, so in that case we have to get it from the parameter
$vm->{vm} = $self->{vm_id} unless $vm->{vm};
return $vm;
}
sub get_vm_tools {
my ($self, %options) = @_;
if ( centreon::plugins::misc::is_empty($self->{vm_id}) && !$self->get_vm_id_from_name(%options) ) {
$self->{output}->add_option_msg(short_msg => "Cannot get VM ID from VM name '" . $self->{vm_name} . "'");
$self->{output}->option_exit();
}
my $tools = $self->request_api(
%options,
'endpoint' => '/vcenter/vm/' . $self->{vm_id} . '/tools',
'method' => 'GET'
);
# Example:
# {
# "auto_update_supported": false,
# "upgrade_policy": "MANUAL",
# "install_attempt_count": 1,
# "version_status": "UNMANAGED",
# "version_number": 12352,
# "run_state": "RUNNING",
# "version": "12352",
# "install_type": "OPEN_VM_TOOLS"
# }
return $tools;
}
sub get_vm_stats {
my ($self, %options) = @_;
if ( centreon::plugins::misc::is_empty($options{vm_id}) && !$self->get_vm_id_from_name(%options) ) {
$self->{output}->add_option_msg(short_msg => "get_vm_stats method cannot get vm ID from vm name");
$self->{output}->option_exit();
}
return $options{custom}->get_stats(
%options,
rsrc_id => $self->{vm_id}
);
}
sub request_api {
my ($self, %options) = @_;
return $options{custom}->request_api(%options);
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (centreon::plugins::misc::is_empty($self->{option_results}->{vm_id})
&& centreon::plugins::misc::is_empty($self->{option_results}->{vm_name})) {
$self->{output}->add_option_msg(short_msg => 'Need to specify either --vm-id or --vm-name option.');
$self->{output}->option_exit();
}
$self->{vm_id} = $self->{option_results}->{vm_id};
$self->{vm_name} = $self->{option_results}->{vm_name};
}
1;
__END__
=head1 VMWARE 8 VM OPTIONS
=over 4
=item B<--vm-id>
Define which VM to monitor based on its resource ID (example: C<vm-16>).
=item B<--vm-name>
Define which VM to monitor based on its name (example: C<WEBSERVER01>).
When possible, it is recommended to use C<--vm-id> instead.
=back
=cut
=head1 NAME
apps::vmware::vsphere8::vm::mode - Template for modes monitoring VMware virtual machine
=head1 SYNOPSIS
use base apps::vmware::vsphere8::vm::mode;
sub set_counters {...}
sub manage_selection {
my ($self, %options) = @_;
$api->set_options(option_results => $option_results);
$api->check_options();
my $response = $api->request_api(endpoint => '/vcenter/vm');
my $vm_cpu_capacity = $self->get_vm_stats(
cid => 'cpu.capacity.provisioned.VM',
rsrc_id => 'vm-18');
=head1 DESCRIPTION
This module provides methods to interact with the VMware vSphere 8 REST API. It handles authentication, caching, and API requests.
=head1 METHODS
=head2 get_vm_stats
$self->get_vm_stats(%options);
Retrieves the VM statistics for the given options using package apps::vmware::vsphere8::custom::api::get_stats()
=over 4
=item * C<%options> - A hash of options. The following keys are supported:
=over 8
=item * C<cid> - The C<cid> (counter id) of the desired metric.
=item * C<vm_id> - The VM's C<rsrc_id> (resource ID) for which to retrieve the statistics. This option is optional if C<vm_name> is provided.
=item * C<vm_name> - The VM's name for which to retrieve the statistics. This option is not used if C<vm_id> is provided, which is the nominal usage of this function.
=back
=back
Returns the statistics for the specified VM.
=cut

View File

@ -0,0 +1,166 @@
#
# Copyright 2025 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::vmware::vsphere8::vm::mode::cpu;
use strict;
use warnings;
use base qw(apps::vmware::vsphere8::vm::mode);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
$options{options}->add_options(
arguments => {}
);
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'cpu_usage', type => 0 }
];
$self->{maps_counters}->{cpu_usage} = [
{
label => 'usage-prct',
type => 1,
nlabel => 'cpu.capacity.usage.percentage',
set => {
output_template => 'CPU average usage is %.2f %%',
key_values => [ { name => 'prct_used' } ],
output_use => 'prct_used',
threshold_use => 'prct_used',
perfdatas => [
{
value => 'prct_used',
template => '%.2f',
min => 0,
max => 100,
unit => '%'
}
]
}
},
{
label => 'usage-frequency',
type => 1,
nlabel => 'cpu.capacity.usage.hertz',
set => {
key_values => [ { name => 'cpu.capacity.usage.VM' }, { name => 'cpu_usage_hertz' }, { name => 'cpu_provisioned_hertz' } ],
output_use => 'cpu.capacity.usage.VM',
threshold_use => 'cpu.capacity.usage.VM',
output_template => 'used frequency is %s kHz',
perfdatas => [
{
value => 'cpu_usage_hertz',
template => '%s',
min => 0,
max => 'cpu_provisioned_hertz',
unit => 'Hz'
}
]
}
}
];
}
sub manage_selection {
my ($self, %options) = @_;
# Set the list of basic counters IDs
my @counters = (
'cpu.capacity.entitlement.VM',
'cpu.capacity.usage.VM'
);
# Get all the needed stats
my %results = map {
$_ => $self->get_vm_stats(%options, cid => $_, vm_id => $self->{vm_id}, vm_name => $self->{vm_name} )
} @counters;
# Example:
# $VAR1 = {
# 'cpu.capacity.usage.VM' => '81.37',
# 'cpu.capacity.entitlement.VM' => '733'
# };
if (!defined($results{'cpu.capacity.usage.VM'}) || !defined($results{'cpu.capacity.entitlement.VM'})) {
$self->{output}->add_option_msg(short_msg => "get_vm_stats function failed to retrieve stats");
$self->{output}->option_exit();
}
$self->{cpu_usage} = {
'prct_used' => 100 * $results{'cpu.capacity.usage.VM'} / $results{'cpu.capacity.entitlement.VM'},
'cpu_usage_hertz' => $results{'cpu.capacity.usage.VM'} * 1000_000,
'cpu_provisioned_hertz' => $results{'cpu.capacity.entitlement.VM'} * 1000_000,
'cpu.capacity.usage.VM' => $results{'cpu.capacity.usage.VM'}
};
return 1;
}
1;
__END__
=head1 MODE
Monitor the CPU stats of a VMware virtual machine through vSphere 8 REST API.
Meaning of the available counters in the VMware API:
- cpu.capacity.entitlement.VM CPU resources in MHz devoted by the ESXi scheduler to the virtual machines and resource pools.
- cpu.capacity.usage.VM CPU usage in MHz during the interval.
The default metrics provided by this plugin are:
- cpu.capacity.usage.hertz based on the API's cpu.capacity.usage.VM counter
- cpu.capacity.usage.percentage based on 100 * cpu.capacity.usage.VM / cpu.capacity.entitlement.VM
=over 8
=item B<--warning-usage-frequency>
Threshold in Hertz.
=item B<--critical-usage-frequency>
Threshold in Hertz.
=item B<--warning-usage-prct>
Threshold in percentage.
=item B<--critical-usage-prct>
Threshold in percentage.
=back
=cut

View File

@ -0,0 +1,156 @@
#
# Copyright 2025 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::vmware::vsphere8::vm::mode::discovery;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use JSON::XS;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
'prettify' => { name => 'prettify' },
'no-identity' => { name => 'no_identity' },
'filter-power-states:s' => { name => 'filter_power_states' },
'filter-folders:s' => { name => 'filter_folders' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub run {
my ($self, %options) = @_;
my $disco_stats;
$disco_stats->{start_time} = time();
my @params;
if (!centreon::plugins::misc::is_empty($self->{option_results}->{filter_power_states})) {
push @params, 'power_states=' . $self->{option_results}->{filter_power_states};
}
if (!centreon::plugins::misc::is_empty($self->{option_results}->{filter_folders})) {
my $folder_ids = $options{custom}->get_folder_ids_by_names('names' => $self->{option_results}->{filter_folders});
push @params, 'folders=' . $folder_ids;
}
my $url_params = '';
$url_params = '?' . join('&', @params) if (@params > 0);
# Retrieve the data
my $response = $options{custom}->request_api('endpoint' => '/vcenter/vm' . $url_params, 'method' => 'GET');
# Format the data for vm discovery
my @results = map {
'vm_name' => $_->{name},
'vmw_vm_id' => $_->{vm},
'power_state' => $_->{power_state},
}, @{$response};
foreach my $vm (@results) {
# if the VM is POWERED_ON and if the tools are available, the vcenter can provide system information
# we skip this if the --no-identity option has been used
my $identity = $options{custom}->get_vm_guest_identity(vm_id => $vm->{vmw_vm_id}) if ($vm->{power_state} eq 'POWERED_ON' && !$self->{option_results}->{no_identity});
# The GuestOSFamily enumerated type defines the valid guest operating system family types reported by a virtual machine.
# WINDOWS : Windows operating system
# LINUX : Linux operating system
# NETWARE : Novell Netware
# SOLARIS : Solaris operating system
# DARWIN : Mac OS operating system
# OTHER : Other operating systems
$vm->{family} = $identity->{family} // '';
# The GuestOS enumerated type defines the valid guest operating system types used for configuring a virtual machine.
# for full list, see https://developer.broadcom.com/xapis/vsphere-automation-api/8.0.3/vcenter/api/vcenter/vm/vm/guest/identity/get/
$vm->{guest_os} = $identity->{name} // '';
$vm->{ip_address} = $identity->{ip_address} // '';
$vm->{guest_os_full} = $identity->{full_name}->{default_message} // '';
}
# Record the metadata
$disco_stats->{end_time} = time();
$disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time};
$disco_stats->{results} = \@results;
$disco_stats->{discovered_items} = scalar(@results);
my $encoded_data;
eval {
if (defined($self->{option_results}->{prettify})) {
$encoded_data = JSON::XS->new->utf8->canonical(1)->pretty->encode($disco_stats);
} else {
$encoded_data = JSON::XS->new->utf8->canonical(1)->encode($disco_stats);
}
};
if ($@) {
$encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}';
}
$self->{output}->output_add(short_msg => $encoded_data);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1);
}
1;
__END__
=head1 MODE
Discover VMware8 virtual machines.
=over 8
=item B<--filter-folders>
Display only virtual machines hold in one of the provided folders (separated by commas).
The strings must be equal (case sensitive).
Example: C<--filter-folders=REDIS_SERVERS>
=item B<--filter-power-states>
Display only virtual machines having power state equal to one of the provided states (separated by commas).
Supported values:
- POWERED_OFF: The virtual machine is powered off.
- POWERED_ON: The virtual machine is powered on.
- SUSPENDED: The virtual machine is suspended.
=item B<--no-identity>
Collecting identity information for all VMs can take a very long time.
If you want to speed up the discovery you can narrow the scope by using C<--filter-power-states> and/or
C<--filter-folders> or, if you only need the VMs names and power states, you may use this option to avoid collecting the
following information: Guest OS, Guest OS family, IP address.
=item B<--prettify>
Prettify JSON output.
=back
=cut

View File

@ -0,0 +1,142 @@
#
# Copyright 2025 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::vmware::vsphere8::vm::mode::memory;
use strict;
use warnings;
use base qw(apps::vmware::vsphere8::vm::mode);
my @counters = (
'mem.capacity.entitlement.VM', # Amount of host physical memory the VM is entitled to, as determined by the ESXi scheduler.
'mem.capacity.usage.VM', # Amount of physical memory actively used.
);
sub custom_memory_output {
my ($self, %options) = @_;
return sprintf(
'Memory used: %s %s used - Usable: %s %s',
$self->{perfdata}->change_bytes(value => $self->{result_values}->{used_bytes}),
$self->{perfdata}->change_bytes(value => $self->{result_values}->{max_bytes})
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'memory', type => 0, message_separator => ' - '}
];
$self->{maps_counters}->{memory} = [
{
label => 'usage-prct',
type => 1,
nlabel => 'memory.usage.percentage',
set => {
key_values => [ { name => 'used_prct' } ],
output_template => '%2.f%% of usable memory is used',
output_use => 'used_prct',
threshold_use => 'used_prct',
perfdatas => [
{
value => 'used_prct',
template => '%.2f',
min => 0,
max => 100,
unit => '%'
}
]
}
},
{
label => 'usage-bytes',
type => 1,
nlabel => 'memory.usage.bytes',
set => {
key_values => [ { name => 'used_bytes' }, { name => 'max_bytes' } ],
closure_custom_output => $self->can('custom_memory_output'),
threshold_use => 'used_bytes',
perfdatas => [
{
value => 'used_bytes',
template => '%d',
max => 'max_bytes',
unit => 'B'
}
]
}
}
];
}
sub manage_selection {
my ($self, %options) = @_;
my %results = map {
$_ => $self->get_vm_stats(%options, cid => $_, vm_id => $self->{vm_id}, vm_name => $self->{vm_name} )
} @counters;
if (!defined($results{'mem.capacity.entitlement.VM'}) || !defined($results{'mem.capacity.usage.VM'})) {
$self->{output}->add_option_msg(short_msg => "get_vm_stats function failed to retrieve stats");
$self->{output}->option_exit();
}
$self->{output}->add_option_msg(long_msg => 'Retrieved value for mem.capacity.entitlement.VM: ' . $results{'mem.capacity.entitlement.VM'});
$self->{output}->add_option_msg(long_msg => 'Retrieved value for mem.capacity.usage.VM: ' . $results{'mem.capacity.usage.VM'});
$self->{memory} = {
used_prct => (100 * $results{'mem.capacity.usage.VM'} / $results{'mem.capacity.entitlement.VM'}),
used_bytes => int(1024 * 1024 * $results{'mem.capacity.usage.VM'}),
max_bytes => int(1024 * 1024 * $results{'mem.capacity.entitlement.VM'})
};
return 1;
}
1;
=head1 MODE
Monitor the memory consumed by the VMware virtual machines through vSphere 8 REST API.
Meaning of the available counters in the VMware API:
- mem.capacity.entitlement.VM Amount of host physical memory the VM is entitled to, as determined by the ESXi scheduler.
- mem.capacity.usage.VM Amount of physical memory actively used.
=over 8
=item B<--warning-usage-bytes>
Threshold in bytes.
=item B<--critical-usage-bytes>
Threshold in bytes.
=item B<--warning-usage-prct>
Threshold in percentage.
=item B<--critical-usage-prct>
Threshold in percentage.
=back
=cut

View File

@ -0,0 +1,104 @@
#
# Copyright 2025 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::vmware::vsphere8::vm::mode::vmstatus;
use base qw(apps::vmware::vsphere8::vm::mode);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_power_status_output {
my ($self, %options) = @_;
return 'power state is ' . $self->{result_values}->{power_state};
}
sub prefix_vm_output {
my ($self, %options) = @_;
return "VM '" . $options{instance_value}->{display} . "', id: '" . $options{instance_value}->{id} . "': ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{
name => 'vm',
type => 1,
cb_prefix_output => 'prefix_vm_output',
message_multiple => 'All VMs are ok'
}
];
$self->{maps_counters}->{vm} = [
{
label => 'power-status',
type => 2,
critical_default => '%{power_state} !~ /^powered_on$/i',
set => {
key_values => [ { name => 'display' }, { name => 'power_state' }, { name => 'id' } ],
closure_custom_output => $self->can('custom_power_status_output'),
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub manage_selection {
my ($self, %options) = @_;
my $vm = $self->get_vm(%options);
$self->{vm}->{$vm->{vm}} = {
display => $vm->{name},
power_state => $vm->{power_state},
id => $vm->{vm}
};
return 1;
}
1;
__END__
=head1 MODE
Monitor the status of VMware VMs through vSphere 8 REST API.
=over 8
=item B<--warning-power-status>
Define the warning threshold for the power status of the VM.
The value should be a Perl expression using the %{power_state} macro.
=item B<--critical-power-status>
Define the critical threshold for the power status of the VM.
The value should be a Perl expression using the %{power_state} macro.
Default: '%{power_state} !~ /^powered_on$/i'
=back
=cut

View File

@ -0,0 +1,301 @@
#
# Copyright 2025 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::vmware::vsphere8::vm::mode::vmtools;
use base qw(apps::vmware::vsphere8::vm::mode);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
my %version_status_explanation = (
NOT_INSTALLED => 'VMware Tools has never been installed.',
CURRENT => 'VMware Tools is installed, and the version is current.',
UNMANAGED => 'VMware Tools is installed, but it is not managed by VMware. This includes open-vm-tools or OSPs which should be managed by the guest operating system.',
TOO_OLD_UNSUPPORTED => 'VMware Tools is installed, but the version is too old.',
SUPPORTED_OLD => 'VMware Tools is installed, supported, but a newer version is available.',
SUPPORTED_NEW => 'VMware Tools is installed, supported, and newer than the version available on the host.',
TOO_NEW => 'VMware Tools is installed, and the version is known to be too new to work correctly with this virtual machine.',
BLACKLISTED => 'VMware Tools is installed, but the installed version is known to have a grave bug and should be immediately upgraded.'
);
sub prefix_vm_output {
my ($self, %options) = @_;
return $options{instance_value}->{id} . ' ';
}
sub custom_install_attempts_output {
my ($self, %options) = @_;
my $desc = 'had ' . $self->{result_values}->{install_attempt_count} . ' install attempts';
$desc .= ' (error messages available in long output with --verbose option)' if ($self->{result_values}->{has_errors});
return $desc;
}
sub custom_upgrade_policy_output {
my ($self, %options) = @_;
my $msg = 'updates are ' . $self->{result_values}->{upgrade_policy} . ' (auto-updates ';
$msg .= 'not ' if ($self->{result_values}->{auto_update_supported} eq 'false');
return $msg . 'allowed)';
}
sub custom_version_status_output {
my ($self, %options) = @_;
return 'version is ' . $self->{result_values}->{version_status} . ' (v' . $self->{result_values}->{version} . ')';
}
sub custom_run_state_output {
my ($self, %options) = @_;
return 'tools are ' . $self->{result_values}->{run_state};
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{
name => 'vm',
type => 0,
display_ok => 1,
cb_prefix_output => 'prefix_vm_output',
message_separator => ' - ',
message_multiple => 'All VMs are ok'
}
];
$self->{maps_counters}->{vm} = [
{
label => 'install-attempts',
nlabel => 'tools.install.attempts.count',
type => 1,
display_ok => 1,
set => {
key_values => [ { name => 'install_attempt_count' }, { name => 'has_errors' } ],
closure_custom_output => $self->can('custom_install_attempts_output'),
perfdatas => [
{ label => 'install-attempts', template => '%d', min => 0 }
]
}
},
{
# Cf https://developer.broadcom.com/xapis/vsphere-automation-api/9.0/data-structures/Vcenter%20Vm%20Tools%20VersionStatus/index.html?scrollString=VersionStatus
# The Vcenter Vm Tools VersionStatus enumerated type defines the version status types of VMware Tools installed in the guest operating system.
label => 'version-status',
type => 2,
display_ok => 1,
warning_default => '%{version_status} =~ /^(SUPPORTED_OLD|TOO_NEW)$/i',
critical_default => '%{version_status} =~ /^(NOT_INSTALLED|TOO_OLD_UNSUPPORTED|BLACKLISTED)$/i',
set => {
key_values => [ { name => 'version_status' }, { name => 'version' } ],
closure_custom_output => $self->can('custom_version_status_output'),
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{
# Cf https://developer.broadcom.com/xapis/vsphere-automation-api/9.0/data-structures/Vcenter%20Vm%20Tools%20UpgradePolicy/index.html?scrollString=Vcenter%20Vm%20Tools%20UpgradePolicy
# Possible values:
# MANUAL: No auto-upgrades for Tools will be performed for this virtual machine. Users must manually invoke the POST /vcenter/vm/{vm}/tools?action=upgrade operation to update Tools.
# UPGRADE_AT_POWER_CYCLE: When the virtual machine is power-cycled, the system checks for a newer version of Tools when the virtual machine is powered on. If it is available, a Tools upgrade is automatically performed on the virtual machine and it is rebooted if necessary.
label => 'upgrade-policy',
type => 2,
display_ok => 1,
set => {
key_values => [ { name => 'auto_update_supported' }, { name => 'upgrade_policy' } ],
closure_custom_output => $self->can('custom_upgrade_policy_output'),
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
},
{
label => 'run-state',
type => 2,
display_ok => 1,
warning_default => '%{run_state} =~ /^NOT_RUNNING$/i',
set => {
key_values => [ { name => 'run_state' } ],
closure_custom_output => $self->can('custom_run_state_output'),
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub parse_tools_version {
my ($version_int) = @_;
# According to (this page)[https://developer.broadcom.com/xapis/vsphere-automation-api/latest/api/vcenter/vm/vm/tools/get/]
# This property will be missing or null if VMWare Tools is not installed.
# This is an integer constructed as follows:
# (((MJR) << 10) + ((MNR) << 5) + (REV))
# Where MJR is tha major verson, MNR is the minor version and REV is the revision.
# Tools version = T
# Tools Version Major = MJR = (T / 1024)
# Tools Version Minor = MNR = ((T % 1024) / 32)
# Tools Version Revision = BASE = ((T % 1024) % 32)
# Tools actual version = MJR.MNR.REV
my @version_str = (
int($version_int / 1024), # major
int($version_int % 1024 / 32), # minor
($version_int % 1024 % 32) # revision
);
return join('.', @version_str);
}
sub manage_selection {
my ($self, %options) = @_;
my $tools = $self->get_vm_tools(%options);
# Example of API response:
# {
# "auto_update_supported": false,
# "upgrade_policy": "MANUAL",
# "install_attempt_count": 1,
# "version_status": "UNMANAGED",
# "version_number": 12352,
# "run_state": "RUNNING",
# "version": "12352",
# "error": {},
# "install_type": "OPEN_VM_TOOLS"
# }
$self->{vm} = {
id => $self->{vm_id} // '',
name => $self->{vm_name} // '',
auto_update_supported => $tools->{auto_update_supported},
install_attempt_count => $tools->{install_attempt_count} // 0,
error => $tools->{error} // {},
upgrade_policy => $tools->{upgrade_policy},
version_status => $tools->{version_status} // '',
install_type => $tools->{install_type} // '',
run_state => $tools->{run_state},
has_errors => 0
};
$self->{vm}->{version} = parse_tools_version($tools->{version_number})
if ($tools->{version_number});
$self->{output}->output_add(long_msg => 'Version status: ' . $tools->{version_status} . ' - Explanation: ' . $version_status_explanation{$tools->{version_status}})
if ( !centreon::plugins::misc::is_empty($tools->{version_status}));
# Example of "error" object:
# {
# "error_type": "ERROR",
# "messages": [
# {
# "args": [],
# "default_message": "An error has occurred while invoking the operation.",
# "id": "com.vmware.api.vcenter.error"
# },
# {
# "args": [],
# "default_message": "Error upgrading VMware Tools.",
# "id": "vmsg.VmToolsUpgradeFault.summary"
# }
# ]
# }
if (defined($self->{vm}->{error}->{messages})) {
# flag the presence of error messages
$self->{vm}->{has_errors} = 1;
# display error messages in long output
foreach my $err (@{ $self->{vm}->{error}->{messages} }) {
my $args = '';
$args = ' Args: '. join(', ', @{ $err->{args} }) if (@{ $err->{args} } > 0);
$self->{output}->output_add(long_msg => 'Error: [' . $err->{id} . '] ' . $err->{default_message} . $args);
}
}
return 1;
}
1;
__END__
=head1 MODE
Monitor the status of VMware Tools on VMs through vSphere 8 REST API.
=over 8
=item B<--warning-install-attempts>
Threshold based on the number of attempts that have been made to install or upgrade the version of Tools installed on
this virtual machine. In case of failed attempts, adding the C<--verbose> option will display the error messages in the
long output.
=item B<--critical-install-attempts>
Threshold based on the number of attempts that have been made to install or upgrade the version of Tools installed on
this virtual machine. In case of failed attempts, adding the C<--verbose> option will display the error messages in the
long output.
=item B<--warning-run-state>
Define the conditions to match for the status to be WARNING based on the Current run state of VMware Tools in the guest
operating system. You can use the following variables: C<%{run_state}> (can be "NOT_RUNNING", "RUNNING"
or "EXECUTING_SCRIPTS").
Default: C<%{run_state} =~ /^NOT_RUNNING$/i>
=item B<--critical-run-state>
Define the conditions to match for the status to be CRITICAL based on the Current run state of VMware Tools in the guest
operating system. You can use the following variables: C<%{run_state}> (can be "NOT_RUNNING", "RUNNING"
or "EXECUTING_SCRIPTS").
=item B<--warning-upgrade-policy>
Define the conditions to match for the status to be WARNING.
You can use the following variables: C<%{auto_update_supported}> (can be "true" or "false"),
C<%{upgrade_policy}> (can be "MANUAL" or "UPGRADE_AT_POWER_CYCLE").
=item B<--critical-upgrade-policy>
Define the conditions to match for the status to be CRITICAL.
You can use the following variables: C<%{auto_update_supported}> (can be "true" or "false"),
C<%{upgrade_policy}> (can be "MANUAL" or "UPGRADE_AT_POWER_CYCLE").
=item B<--warning-version-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: C<%{version_status}> (can be "NOT_INSTALLED", "CURRENT", "UNMANAGED",
"TOO_OLD_UNSUPPORTED", "SUPPORTED_OLD", "SUPPORTED_NEW", "TOO_NEW" or "BLACKLISTED") and
C<%{version}> (example: "v12.3.0").
Default: C<%{version_status} =~ /^(SUPPORTED_OLD|TOO_NEW)$/i>
=item B<--critical-version-status>
Define the conditions to match for the status to be CRITICAL.
You can use the following variables: C<%{version_status}> (can be "NOT_INSTALLED", "CURRENT", "UNMANAGED",
"TOO_OLD_UNSUPPORTED", "SUPPORTED_OLD", "SUPPORTED_NEW", "TOO_NEW" or "BLACKLISTED") and
C<%{version}> (example: "v12.3.0").
Default: C<%{version_status} =~ /^(NOT_INSTALLED|TOO_OLD_UNSUPPORTED|BLACKLISTED)$/i>
=back
=cut

View File

@ -0,0 +1,53 @@
#
# Copyright 2025 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::vmware::vsphere8::vm::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '0.1';
$self->{modes} = {
'cpu' => 'apps::vmware::vsphere8::vm::mode::cpu',
'discovery' => 'apps::vmware::vsphere8::vm::mode::discovery',
'memory' => 'apps::vmware::vsphere8::vm::mode::memory',
'vm-status' => 'apps::vmware::vsphere8::vm::mode::vmstatus',
'vm-tools' => 'apps::vmware::vsphere8::vm::mode::vmtools',
};
$self->{custom_modes}->{api} = 'apps::vmware::vsphere8::custom::api';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Monitor VMware virtual machines through vSphere 8 REST API.
=cut

View File

@ -0,0 +1,35 @@
*** Settings ***
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}mockoon.json
${CMD} ${CENTREON_PLUGINS} --plugin=apps::vmware::vsphere8::vm::plugin
... --mode=cpu
... --password=C3POR2P2
... --username=obi-wan
... --hostname=127.0.0.1
... --proto=http
... --port=3000
... --vm-id=vm-7722
*** Test Cases ***
Cpu ${tc}
[Tags] apps api vmware vsphere8 vm
${command} Catenate ${CMD} ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} UNKNOWN: no data for host vm-7722 counter cpu.capacity.entitlement.VM at the moment. - get_vm_stats function failed to retrieve stats The counter cpu.capacity.entitlement.VM was not recorded for resource vm-7722 before. It will now (creating acq_spec). The counter cpu.capacity.usage.VM was not recorded for resource vm-7722 before. It will now (creating acq_spec).
... 2 ${EMPTY} OK: CPU average usage is 11.13 %, used frequency is 81.56 kHz | 'cpu.capacity.usage.percentage'=11.13%;;;0;100 'cpu.capacity.usage.hertz'=81560000Hz;;;0;733000000
... 3 --warning-usage-prct=5 WARNING: CPU average usage is 11.13 % | 'cpu.capacity.usage.percentage'=11.13%;0:5;;0;100 'cpu.capacity.usage.hertz'=81560000Hz;;;0;733000000
... 4 --critical-usage-prct=5 CRITICAL: CPU average usage is 11.13 % | 'cpu.capacity.usage.percentage'=11.13%;;0:5;0;100 'cpu.capacity.usage.hertz'=81560000Hz;;;0;733000000
... 5 --warning-usage-frequency=5 WARNING: used frequency is 81.56 kHz | 'cpu.capacity.usage.percentage'=11.13%;;;0;100 'cpu.capacity.usage.hertz'=81560000Hz;0:5;;0;733000000
... 6 --critical-usage-frequency=5 CRITICAL: used frequency is 81.56 kHz | 'cpu.capacity.usage.percentage'=11.13%;;;0;100 'cpu.capacity.usage.hertz'=81560000Hz;;0:5;0;733000000

View File

@ -0,0 +1,37 @@
*** Settings ***
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}mockoon.json
${CMD} ${CENTREON_PLUGINS} --plugin=apps::vmware::vsphere8::vm::plugin
... --password=C3POR2P2
... --username=obi-wan
... --mode=discovery
... --hostname=127.0.0.1
... --proto=http
... --port=3000
*** Test Cases ***
Discovery ${tc}
[Tags] apps api vmware vsphere8 vm discovery
${command} Catenate ${CMD} ${extra_options}
Ctn Run Command And Check Result As Json ${command} ${expected_result}
Examples: tc extra_options expected_result --
... 1 ${EMPTY}
... {"discovered_items":3,"duration":0,"end_time":1756740577,"results":[{"family":"","guest_os":"","guest_os_full":"","ip_address":"","power_state":"POWERED_OFF","vm_name":"web-server-01","vmw_vm_id":"vm-7657"},{"family":"LINUX","guest_os":"DEBIAN_12_64","guest_os_full":"Debian GNU/Linux 12 (64-bit)","ip_address":"172.16.2.1","power_state":"POWERED_ON","vm_name":"db-server-01","vmw_vm_id":"vm-7722"},{"family":"WINDOWS","guest_os":"WINDOWS_SERVER_2021","guest_os_full":"Microsoft Windows Server 2022 (64-bit)","ip_address":"172.16.2.12","power_state":"POWERED_ON","vm_name":"web-server-02","vmw_vm_id":"vm-1234"}],"start_time":1756740577}
... 2 --filter-power-states=POWERED_ON
... {"discovered_items":2,"duration":0,"end_time":1756740577,"results":[{"family":"LINUX","guest_os":"DEBIAN_12_64","guest_os_full":"Debian GNU/Linux 12 (64-bit)","ip_address":"172.16.2.1","power_state":"POWERED_ON","vm_name":"db-server-01","vmw_vm_id":"vm-7722"},{"family":"WINDOWS","guest_os":"WINDOWS_SERVER_2021","guest_os_full":"Microsoft Windows Server 2022 (64-bit)","ip_address":"172.16.2.12","power_state":"POWERED_ON","vm_name":"web-server-02","vmw_vm_id":"vm-1234"}],"start_time":1756740577}
... 3 --filter-power-states=POWERED_OFF
... {"discovered_items":1,"duration":0,"end_time":1756740577,"results":[{"family":"","guest_os":"","guest_os_full":"","ip_address":"","power_state":"POWERED_OFF","vm_name":"web-server-01","vmw_vm_id":"vm-7657"}],"start_time":1756740577}
... 4 --filter-folders=My_Dir
... {"discovered_items":1,"duration":0,"end_time":1756740577,"results":[{"family":"LINUX","guest_os":"DEBIAN_12_64","guest_os_full":"Debian GNU/Linux 12 (64-bit)","ip_address":"172.16.2.1","power_state":"POWERED_ON","vm_name":"db-server-01","vmw_vm_id":"vm-7722"}],"start_time":1756740577}

View File

@ -0,0 +1,35 @@
*** Settings ***
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}mockoon.json
${CMD} ${CENTREON_PLUGINS} --plugin=apps::vmware::vsphere8::vm::plugin
... --mode=memory
... --password=C3POR2P2
... --username=obi-wan
... --hostname=127.0.0.1
... --proto=http
... --port=3000
... --vm-id=vm-22
*** Test Cases ***
Memory ${tc}
[Tags] apps api vmware vsphere8 vm
${command} Catenate ${CMD} ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} UNKNOWN: no data for host vm-22 counter mem.capacity.entitlement.VM at the moment. - get_vm_stats function failed to retrieve stats The counter mem.capacity.entitlement.VM was not recorded for resource vm-22 before. It will now (creating acq_spec). The counter mem.capacity.usage.VM was not recorded for resource vm-22 before. It will now (creating acq_spec).
... 2 ${EMPTY} OK: 17% of usable memory is used - Memory used: 285.55 MB used - Usable: 1.60 GB | 'memory.usage.percentage'=17.41%;;;0;100 'memory.usage.bytes'=299420876B;;;;1720126013
... 3 --warning-usage-prct=0:0 WARNING: 17% of usable memory is used | 'memory.usage.percentage'=17.41%;0:0;;0;100 'memory.usage.bytes'=299420876B;;;;1720126013
... 4 --critical-usage-prct=0:0 CRITICAL: 17% of usable memory is used | 'memory.usage.percentage'=17.41%;;0:0;0;100 'memory.usage.bytes'=299420876B;;;;1720126013
... 5 --warning-usage-bytes=0:0 WARNING: Memory used: 285.55 MB used - Usable: 1.60 GB | 'memory.usage.percentage'=17.41%;;;0;100 'memory.usage.bytes'=299420876B;0:0;;;1720126013
... 6 --critical-usage-bytes=0:0 CRITICAL: Memory used: 285.55 MB used - Usable: 1.60 GB | 'memory.usage.percentage'=17.41%;;;0;100 'memory.usage.bytes'=299420876B;;0:0;;1720126013

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
*** Settings ***
Documentation Forcepoint SD-WAN Standard SNMP Mode
Resource ${CURDIR}${/}../..${/}..${/}..${/}resources/import.resource
Suite Setup Ctn Generic Suite Setup
Suite Teardown Ctn Generic Suite Teardown
Test Timeout 120s
*** Variables ***
${CMD} ${CENTREON_PLUGINS} --plugin=apps::vmware::vsphere8::vm::plugin
*** Test Cases ***
Standard ${tc} - ${mode}
[Tags] apps api vmware vsphere8 vm
${command} Catenate
... ${CMD}
... --mode=${mode}
... --help
Ctn Run Command And Check Result As Regexp ${command} ${expected_result}
Examples: tc mode expected_result --
... 1 cpu ^Plugin Description:
... 2 discovery ^Plugin Description:
... 3 memory ^Plugin Description:
... 4 vm-status ^Plugin Description:
... 5 vm-tools ^Plugin Description:

View File

@ -0,0 +1,41 @@
*** Settings ***
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
Test Setup Ctn Cleanup Cache
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}mockoon.json
${CMD} ${CENTREON_PLUGINS} --plugin=apps::vmware::vsphere8::vm::plugin
... --mode=vm-status
... --password=C3POR2P2
... --username=obi-wan
... --hostname=127.0.0.1
... --proto=http
... --port=3000
*** Test Cases ***
Vm-Status ${tc}
[Tags] apps api vmware vsphere8 vm
${command} Catenate ${CMD} ${filter_vm} ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc filter_vm extraoptions expected_result --
... 1 --vm-name=db-server-01 ${EMPTY} OK: VM 'db-server-01', id: 'vm-7722': power state is POWERED_ON
... 2 --vm-name=web-server-01 ${EMPTY} CRITICAL: VM 'web-server-01', id: 'vm-7657': power state is POWERED_OFF
... 3 --vm-name=vm3.acme.com ${EMPTY} UNKNOWN: No VM found.
... 4 --vm-id=vm-7722 ${EMPTY} OK: VM 'db-server-01', id: 'vm-7722': power state is POWERED_ON
... 5 --vm-id=vm-7657 ${EMPTY} CRITICAL: VM 'web-server-01', id: 'vm-7657': power state is POWERED_OFF
... 6 --vm-id=vm-3 ${EMPTY} UNKNOWN: No VM found.
... 7 --vm-id=vm-3000000 --warning-power-status='\\\%{power_state} =~ /^powered_on$/i' UNKNOWN: No VM found.
... 8 --vm-id=vm-7722 --critical-power-status='\\\%{power_state} =~ /^powered_on$/i' CRITICAL: VM 'db-server-01', id: 'vm-7722': power state is POWERED_ON
... 9 --vm-id=vm-7657 --critical-power-status='\\\%{power_state} =~ /^powered_on$/i' OK: VM 'web-server-01', id: 'vm-7657': power state is POWERED_OFF
... 10 --vm-id=vm-7722 --warning-power-status='\\\%{power_state} =~ /^powered_on$/i' WARNING: VM 'db-server-01', id: 'vm-7722': power state is POWERED_ON
... 11 --vm-id=vm-7657 --warning-power-status='\\\%{power_state} =~ /^powered_on$/i' CRITICAL: VM 'web-server-01', id: 'vm-7657': power state is POWERED_OFF
... 12 --vm-id=vm-3 --vm-name=web-server-01 ${EMPTY} CRITICAL: VM 'web-server-01', id: 'vm-7657': power state is POWERED_OFF

View File

@ -0,0 +1,61 @@
*** Settings ***
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
Test Setup Ctn Cleanup Cache
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}mockoon.json
${CMD} ${CENTREON_PLUGINS} --plugin=apps::vmware::vsphere8::vm::plugin
... --mode=vm-tools
... --password=C3POR2P2
... --username=obi-wan
... --hostname=127.0.0.1
... --proto=http
... --port=3000
*** Test Cases ***
Vm-Tools ${tc}
[Tags] apps api vmware vsphere8 vm
${command} Catenate ${CMD} ${filter_vm} ${extraoptions}
Ctn Run Command And Check Result As Strings ${command} ${expected_result}
Examples: tc filter_vm extraoptions expected_result --
... 1 --vm-name=db-server-01 ${EMPTY} OK: vm-7722 had 1 install attempts - version is UNMANAGED (v12.2.0) - updates are MANUAL (auto-updates not allowed) - tools are RUNNING | 'tools.install.attempts.count'=1;;;0;
... 2 --vm-name=web-server-01 ${EMPTY} OK: vm-7657 had 4 install attempts - version is CURRENT (v12.3.0) - updates are MANUAL (auto-updates allowed) - tools are RUNNING | 'tools.install.attempts.count'=4;;;0;
... 3 --vm-name=web-server-02 ${EMPTY} WARNING: vm-1234 tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;;0;
... 4 --vm-name=web-server-03 ${EMPTY} UNKNOWN: Cannot get VM ID from VM name 'web-server-03'
... 5 --vm-id=vm-7722 ${EMPTY} OK: vm-7722 had 1 install attempts - version is UNMANAGED (v12.2.0) - updates are MANUAL (auto-updates not allowed) - tools are RUNNING | 'tools.install.attempts.count'=1;;;0;
... 6 --vm-id=vm-7657 ${EMPTY} OK: vm-7657 had 4 install attempts - version is CURRENT (v12.3.0) - updates are MANUAL (auto-updates allowed) - tools are RUNNING | 'tools.install.attempts.count'=4;;;0;
... 7 --vm-id=vm-1234 ${EMPTY} WARNING: vm-1234 tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;;0;
... 8 --vm-id=vm-3000000 ${EMPTY} UNKNOWN: API returns error of type NOT_FOUND: [Id: com.vmware.api.vcenter.vm.not_found - Msg: Virtual machine with identifier 'vm-3000000:c186dc36-76b6-4435-b5f3-cb1e9678a67e' does not exist. (vm-3000000:c186dc36-76b6-4435-b5f3-cb1e9678a67e)]
... 9 --vm-id=vm-7722 --warning-install-attempts=0 WARNING: vm-7722 had 1 install attempts | 'tools.install.attempts.count'=1;0:0;;0;
... 10 --vm-id=vm-7657 --warning-install-attempts=0 WARNING: vm-7657 had 4 install attempts | 'tools.install.attempts.count'=4;0:0;;0;
... 11 --vm-id=vm-1234 --warning-install-attempts=0 WARNING: vm-1234 had 4 install attempts (error messages available in long output with --verbose option) - tools are NOT_RUNNING | 'tools.install.attempts.count'=4;0:0;;0;
... 13 --vm-id=vm-7722 --critical-install-attempts=0 CRITICAL: vm-7722 had 1 install attempts | 'tools.install.attempts.count'=1;;0:0;0;
... 14 --vm-id=vm-7657 --critical-install-attempts=0 CRITICAL: vm-7657 had 4 install attempts | 'tools.install.attempts.count'=4;;0:0;0;
... 15 --vm-id=vm-1234 --critical-install-attempts=0 CRITICAL: vm-1234 had 4 install attempts (error messages available in long output with --verbose option) - tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;0:0;0;
... 17 --vm-id=vm-7722 --warning-run-state=1 WARNING: vm-7722 tools are RUNNING | 'tools.install.attempts.count'=1;;;0;
... 18 --vm-id=vm-7657 --warning-run-state=1 WARNING: vm-7657 tools are RUNNING | 'tools.install.attempts.count'=4;;;0;
... 19 --vm-id=vm-1234 --warning-run-state=1 WARNING: vm-1234 tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;;0;
... 21 --vm-id=vm-7722 --critical-run-state=1 CRITICAL: vm-7722 tools are RUNNING | 'tools.install.attempts.count'=1;;;0;
... 22 --vm-id=vm-7657 --critical-run-state=1 CRITICAL: vm-7657 tools are RUNNING | 'tools.install.attempts.count'=4;;;0;
... 23 --vm-id=vm-1234 --critical-run-state=1 CRITICAL: vm-1234 tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;;0;
... 25 --vm-id=vm-7722 --warning-upgrade-policy=1 WARNING: vm-7722 updates are MANUAL (auto-updates not allowed) | 'tools.install.attempts.count'=1;;;0;
... 26 --vm-id=vm-7657 --warning-upgrade-policy=1 WARNING: vm-7657 updates are MANUAL (auto-updates allowed) | 'tools.install.attempts.count'=4;;;0;
... 27 --vm-id=vm-1234 --warning-upgrade-policy=1 WARNING: vm-1234 updates are MANUAL (auto-updates not allowed) - tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;;0;
... 29 --vm-id=vm-7722 --critical-upgrade-policy=1 CRITICAL: vm-7722 updates are MANUAL (auto-updates not allowed) | 'tools.install.attempts.count'=1;;;0;
... 30 --vm-id=vm-7657 --critical-upgrade-policy=1 CRITICAL: vm-7657 updates are MANUAL (auto-updates allowed) | 'tools.install.attempts.count'=4;;;0;
... 31 --vm-id=vm-1234 --critical-upgrade-policy=1 CRITICAL: vm-1234 updates are MANUAL (auto-updates not allowed) - tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;;0;
... 33 --vm-id=vm-7722 --warning-version-status=1 WARNING: vm-7722 version is UNMANAGED (v12.2.0) | 'tools.install.attempts.count'=1;;;0;
... 34 --vm-id=vm-7657 --warning-version-status=1 WARNING: vm-7657 version is CURRENT (v12.3.0) | 'tools.install.attempts.count'=4;;;0;
... 35 --vm-id=vm-1234 --warning-version-status=1 WARNING: vm-1234 version is CURRENT (v12.3.0) - tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;;0;
... 37 --vm-id=vm-7722 --critical-version-status=1 CRITICAL: vm-7722 version is UNMANAGED (v12.2.0) | 'tools.install.attempts.count'=1;;;0;
... 38 --vm-id=vm-7657 --critical-version-status=1 CRITICAL: vm-7657 version is CURRENT (v12.3.0) | 'tools.install.attempts.count'=4;;;0;
... 39 --vm-id=vm-1234 --critical-version-status=1 CRITICAL: vm-1234 version is CURRENT (v12.3.0) - tools are NOT_RUNNING | 'tools.install.attempts.count'=4;;;0;