Vmware vminfo modernize (#15008)

* Vmware vminfo
Remove legacy file and migrate to OS discovery

* tighter

* ios_stp-vlans working correctly now

* Make vmwVmGuestOS nullable

* Discover os info too

* VM Info module

* Apply fixes from StyleCI

* Fix log severity

* Fix log severity (more)

* VM Info module

* Poll with ESXi too because it is lightweight
add test data

* poller data now too

---------

Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
Tony Murray 2023-10-05 19:49:26 -05:00 committed by GitHub
parent bec7a9f449
commit 087d588102
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 990 additions and 446 deletions

View File

@ -0,0 +1,39 @@
<?php
/*
* VminfoDiscovery.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Interfaces\Discovery;
use App\Models\Vminfo;
use Illuminate\Support\Collection;
interface VminfoDiscovery
{
/**
* Discover all the VMs and return a collection of Vminfo models
*
* @return Collection<Vminfo>
*/
public function discoverVminfo(): Collection;
}

View File

@ -0,0 +1,40 @@
<?php
/*
* VminfoPolling.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Interfaces\Polling;
use App\Models\Vminfo;
use Illuminate\Support\Collection;
interface VminfoPolling
{
/**
* Poll the given VMs
*
* @param Collection<Vminfo> $vms
* @return Collection<Vminfo>
*/
public function pollVminfo(Collection $vms): Collection;
}

View File

@ -26,7 +26,9 @@
namespace LibreNMS\Modules;
use App\Models\Device;
use App\Models\Eventlog;
use App\Models\Location;
use LibreNMS\Enum\Severity;
use LibreNMS\Interfaces\Data\DataStorageInterface;
use LibreNMS\Interfaces\Module;
use LibreNMS\Interfaces\Polling\OSPolling;
@ -77,23 +79,17 @@ class Os implements Module
if ($os instanceof OSPolling) {
$os->pollOS($datastore);
} else {
// legacy poller files
global $graphs, $device;
if (empty($device)) {
$device = $os->getDeviceArray();
}
$device = $os->getDeviceArray();
$location = null;
if (is_file(base_path('/includes/polling/os/' . $device['os'] . '.inc.php'))) {
// OS Specific
Eventlog::log("Warning: OS {$device['os']} using deprecated polling method", $deviceModel, 'poller', Severity::Error);
include base_path('/includes/polling/os/' . $device['os'] . '.inc.php');
} elseif (! empty($device['os_group']) && is_file(base_path('/includes/polling/os/' . $device['os_group'] . '.inc.php'))) {
// OS Group Specific
Eventlog::log("Warning: OS {$device['os']} using deprecated polling method", $deviceModel, 'poller', Severity::Error);
include base_path('/includes/polling/os/' . $device['os_group'] . '.inc.php');
} else {
echo "Generic :(\n";
}
// handle legacy variables, sometimes they are false

119
LibreNMS/Modules/Vminfo.php Normal file
View File

@ -0,0 +1,119 @@
<?php
/*
* Vminfo.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Modules;
use App\Models\Device;
use App\Observers\ModuleModelObserver;
use LibreNMS\Config;
use LibreNMS\DB\SyncsModels;
use LibreNMS\Interfaces\Data\DataStorageInterface;
use LibreNMS\Interfaces\Discovery\VminfoDiscovery;
use LibreNMS\Interfaces\Polling\VminfoPolling;
use LibreNMS\OS;
use LibreNMS\Polling\ModuleStatus;
class Vminfo implements \LibreNMS\Interfaces\Module
{
use SyncsModels;
/**
* @inheritDoc
*/
public function dependencies(): array
{
return [];
}
public function shouldDiscover(OS $os, ModuleStatus $status): bool
{
// libvirt does not use snmp, only ssh tunnels
if (! Config::get('enable_libvirt') && $os->getDevice()->snmp_disable) {
return false;
}
return $status->isEnabled() && $os->getDevice()->status && $os instanceof VminfoDiscovery;
}
/**
* @inheritDoc
*/
public function discover(OS $os): void
{
if ($os instanceof VminfoDiscovery) {
$vms = $os->discoverVminfo();
ModuleModelObserver::observe(\App\Models\Vminfo::class);
$this->syncModels($os->getDevice(), 'vminfo', $vms);
}
echo PHP_EOL;
}
public function shouldPoll(OS $os, ModuleStatus $status): bool
{
return $status->isEnabled() && ! $os->getDevice()->snmp_disable && $os->getDevice()->status && $os instanceof VminfoPolling;
}
/**
* @inheritDoc
*/
public function poll(OS $os, DataStorageInterface $datastore): void
{
if ($os->getDevice()->vminfo->isEmpty()) {
return;
}
if ($os instanceof VminfoPolling) {
$vms = $os->pollVminfo($os->getDevice()->vminfo);
ModuleModelObserver::observe(\App\Models\Vminfo::class);
$this->syncModels($os->getDevice(), 'vminfo', $vms);
return;
}
// just run discovery again
$this->discover($os);
}
/**
* @inheritDoc
*/
public function cleanup(Device $device): void
{
$device->vminfo()->delete();
}
/**
* @inheritDoc
*/
public function dump(Device $device)
{
return [
'vminfo' => $device->vminfo()->orderBy('vmwVmVMID')
->get()->map->makeHidden(['id', 'device_id']),
];
}
}

View File

@ -94,10 +94,8 @@ class OS implements
/**
* OS constructor. Not allowed to be created directly. Use OS::make()
*
* @param array $device
*/
protected function __construct(&$device)
protected function __construct(array &$device)
{
$this->device = &$device;
$this->graphs = [];
@ -231,11 +229,8 @@ class OS implements
* OS Factory, returns an instance of the OS for this device
* If no specific OS is found, Try the OS group.
* Otherwise, returns Generic
*
* @param array $device device array, must have os set
* @return OS
*/
public static function make(&$device)
public static function make(array &$device): OS
{
if (isset($device['os'])) {
// load os definition and populate os_group

View File

@ -25,9 +25,8 @@ namespace LibreNMS\OS;
use App\Models\Device;
use LibreNMS\Interfaces\Discovery\OSDiscovery;
use LibreNMS\OS;
class Beagleboard extends OS implements OSDiscovery
class Beagleboard extends Linux implements OSDiscovery
{
/**
* Retrieve basic information about the OS / device

54
LibreNMS/OS/Linux.php Normal file
View File

@ -0,0 +1,54 @@
<?php
/*
* Linux.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\OS;
use Illuminate\Support\Collection;
use LibreNMS\Interfaces\Discovery\VminfoDiscovery;
use LibreNMS\OS\Traits\VminfoLibvirt;
use LibreNMS\OS\Traits\VminfoVmware;
class Linux extends Shared\Unix implements VminfoDiscovery
{
// NOTE: Only Linux specific stuff should go here, most things should be in Unix
use VminfoLibvirt, VminfoVmware {
VminfoLibvirt::discoverVminfo as discoverLibvirtVminfo;
VminfoVmware::discoverVmInfo as discoverVmwareVminfo;
}
public function discoverVmInfo(): Collection
{
$vms = $this->discoverLibvirtVminfo();
if ($vms->isNotEmpty()) {
return $vms;
}
echo PHP_EOL;
return $this->discoverVmwareVminfo();
}
}

View File

@ -0,0 +1,166 @@
<?php
/*
* VminfoLibvirt.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\OS\Traits;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use LibreNMS\Config;
use LibreNMS\Enum\PowerState;
trait VminfoLibvirt
{
public function discoverVminfo(): Collection
{
echo 'LibVirt VM: ';
if (! Config::get('enable_libvirt')) {
echo 'not configured';
}
$vms = new Collection;
$ssh_ok = 0;
$userHostname = $this->getDevice()->hostname;
if (Config::has('libvirt_username')) {
$userHostname = Config::get('libvirt_username') . '@' . $userHostname;
}
foreach (Config::get('libvirt_protocols') as $method) {
if (Str::contains($method, 'qemu')) {
$uri = $method . '://' . $userHostname . '/system';
} else {
$uri = $method . '://' . $userHostname;
}
if (Str::contains($method, 'ssh') && ! $ssh_ok) {
// Check if we are using SSH if we can log in without password - without blocking the discovery
// Also automatically add the host key so discovery doesn't block on the yes/no question, and run echo so we don't get stuck in a remote shell ;-)
exec('ssh -o "StrictHostKeyChecking no" -o "PreferredAuthentications publickey" -o "IdentitiesOnly yes" ' . $userHostname . ' echo -e', $out, $ret);
if ($ret != 255) {
$ssh_ok = 1;
}
}
if ($ssh_ok || ! Str::contains($method, 'ssh')) {
// Fetch virtual machine list
unset($domlist);
exec(Config::get('virsh') . ' -rc ' . $uri . ' list', $domlist);
foreach ($domlist as $dom) {
[$dom_id] = explode(' ', trim($dom), 2);
if (is_numeric($dom_id)) {
// Fetch the Virtual Machine information.
unset($vm_info_array);
exec(Config::get('virsh') . ' -rc ' . $uri . ' dumpxml ' . $dom_id, $vm_info_array);
// Example xml:
// <domain type='kvm' id='3'>
// <name>moo.example.com</name>
// <uuid>48cf6378-6fd5-4610-0611-63dd4b31cfd6</uuid>
// <memory>1048576</memory>
// <currentMemory>1048576</currentMemory>
// <vcpu>8</vcpu>
// <os>
// <type arch='x86_64' machine='pc-0.12'>hvm</type>
// <boot dev='hd'/>
// </os>
// <features>
// <acpi/>
// (...)
// See spec at https://libvirt.org/formatdomain.html
// Convert array to string
$vm_info_xml = implode($vm_info_array);
$xml = simplexml_load_string('<?xml version="1.0"?> ' . $vm_info_xml);
Log::debug($xml);
// libvirt does not supply this
exec(Config::get('virsh') . ' -rc ' . $uri . ' domstate ' . $dom_id, $vm_state);
$vmwVmState = PowerState::STATES[strtolower($vm_state[0])] ?? PowerState::UNKNOWN;
$vmwVmMemSize = $xml->memory;
// Convert memory size to MiB
switch ($xml->memory['unit']) {
case 'T':
case 'TiB':
$vmwVmMemSize = $xml->memory * 1048576;
break;
case 'TB':
$vmwVmMemSize = $xml->memory * 1000000;
break;
case 'G':
case 'GiB':
$vmwVmMemSize = $xml->memory * 1024;
break;
case 'GB':
$vmwVmMemSize = $xml->memory * 1000;
break;
case 'M':
case 'MiB':
break;
case 'MB':
$vmwVmMemSize = $xml->memory * 1000000 / 1048576;
break;
case 'KB':
$vmwVmMemSize = $xml->memory / 1000;
break;
case 'b':
case 'bytes':
$vmwVmMemSize = $xml->memory / 1048576;
break;
default:
// KiB or k or no value
$vmwVmMemSize = $xml->memory / 1024;
break;
}
// Save the discovered Virtual Machine.
$vms->push(new \App\Models\Vminfo([
'vmtype' => 'libvirt',
'vmwVmVMID' => $dom_id,
'vmwVmState' => $vmwVmState,
'vmwVmGuestOS' => '',
'vmwVmDisplayName' => $xml->name,
'vmwVmMemSize' => $vmwVmMemSize,
'vmwVmCpus' => $xml->vcpu['current'] ?? $xml->vcpu,
]));
}
}
}
// If we found VMs, don't cycle the other protocols anymore.
if ($vms->isNotEmpty()) {
break;
}
}
return $vms;
}
}

View File

@ -0,0 +1,67 @@
<?php
/*
* VminfoVmware.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\OS\Traits;
use App\Models\Vminfo;
use Illuminate\Support\Collection;
use LibreNMS\Enum\PowerState;
trait VminfoVmware
{
public function discoverVmInfo(): Collection
{
echo 'VMware VM: ';
/*
* Fetch the Virtual Machine information.
*
* VMWARE-VMINFO-MIB::vmwVmDisplayName.224 = STRING: My First VM
* VMWARE-VMINFO-MIB::vmwVmGuestOS.224 = STRING: windows7Server64Guest
* VMWARE-VMINFO-MIB::vmwVmMemSize.224 = INTEGER: 8192 megabytes
* VMWARE-VMINFO-MIB::vmwVmState.224 = STRING: poweredOn
* VMWARE-VMINFO-MIB::vmwVmVMID.224 = INTEGER: 224
* VMWARE-VMINFO-MIB::vmwVmCpus.224 = INTEGER: 2
*/
$vm_info = \SnmpQuery::hideMib()->walk('VMWARE-VMINFO-MIB::vmwVmTable');
return $vm_info->mapTable(function ($data, $vmwVmVMID) {
$data['vm_type'] = 'vmware';
$data['vmwVmVMID'] = $vmwVmVMID;
$data['vmwVmState'] = PowerState::STATES[$data['vmwVmState']] ?? PowerState::UNKNOWN;
/*
* If VMware Tools is not running then don't overwrite the GuestOS with the error
* message, but just leave it as it currently is.
*/
if (str_contains($data['vmwVmGuestOS'], 'tools not ')) {
unset($data['vmwVmGuestOS']);
}
return new Vminfo($data);
});
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* VmwareEsxi.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* @link https://www.librenms.org
*
* @copyright 2023 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\OS;
use Illuminate\Support\Collection;
use LibreNMS\Interfaces\Discovery\VminfoDiscovery;
use LibreNMS\Interfaces\Polling\VminfoPolling;
use LibreNMS\OS\Traits\VminfoVmware;
class VmwareEsxi extends \LibreNMS\OS implements VminfoDiscovery, VminfoPolling
{
use VminfoVmware;
public function pollVminfo(Collection $vms): Collection
{
// no VMs, assume there aren't any
if ($vms->isEmpty()) {
return $vms;
}
return $this->discoverVmInfo(); // just do the same thing as discovery.
}
}

View File

@ -7,16 +7,26 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Str;
use LibreNMS\Interfaces\Models\Keyable;
use LibreNMS\Util\Html;
use LibreNMS\Util\Number;
use LibreNMS\Util\Rewrite;
class Vminfo extends DeviceRelatedModel
class Vminfo extends DeviceRelatedModel implements Keyable
{
use HasFactory;
protected $table = 'vminfo';
public $timestamps = false;
protected $fillable = [
'vm_type',
'vmwVmVMID',
'vmwVmDisplayName',
'vmwVmGuestOS',
'vmwVmMemSize',
'vmwVmCpus',
'vmwVmState',
];
public function getStateLabelAttribute(): array
{
@ -56,4 +66,9 @@ class Vminfo extends DeviceRelatedModel
{
return $this->hasOne(\App\Models\Device::class, 'hostname', 'vmwVmDisplayName');
}
public function getCompositeKey()
{
return $this->vm_type . $this->vmwVmVMID;
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace App\Observers;
use App\Models\Eventlog;
use App\Models\Vminfo;
use LibreNMS\Enum\Severity;
class VminfoObserver
{
/**
* Handle the Vminfo "created" event.
*
* @param \App\Models\Vminfo $vminfo
* @return void
*/
public function created(Vminfo $vminfo)
{
Eventlog::log('Virtual Machine added: ' . $vminfo->vmwVmDisplayName . " ($vminfo->vmwVmMemSize GB / $vminfo->vmwVmCpus vCPU)", $vminfo->device_id, 'vm', Severity::Notice, $vminfo->vmwVmVMID);
}
/**
* Handle the Vminfo "updated" event.
*
* @param \App\Models\Vminfo $vminfo
* @return void
*/
public function updating(Vminfo $vminfo)
{
foreach ($vminfo->getDirty() as $field => $value) {
Eventlog::log($vminfo->vmwVmDisplayName . ' (' . preg_replace('/^vmwVm/', '', $field) . ') -> ' . $value, $vminfo->device_id, 'vm');
}
}
/**
* Handle the Vminfo "deleted" event.
*
* @param \App\Models\Vminfo $vminfo
* @return void
*/
public function deleted(Vminfo $vminfo)
{
Eventlog::log('Virtual Machine removed: ' . $vminfo->vmwVmDisplayName, $vminfo->device_id, 'vm', Severity::Warning, $vminfo->vmwVmVMID);
}
/**
* Handle the Vminfo "restored" event.
*
* @param \App\Models\Vminfo $vminfo
* @return void
*/
public function restored(Vminfo $vminfo)
{
//
}
/**
* Handle the Vminfo "force deleted" event.
*
* @param \App\Models\Vminfo $vminfo
* @return void
*/
public function forceDeleted(Vminfo $vminfo)
{
//
}
}

View File

@ -142,6 +142,7 @@ class AppServiceProvider extends ServiceProvider
\App\Models\Service::observe(\App\Observers\ServiceObserver::class);
\App\Models\Stp::observe(\App\Observers\StpObserver::class);
\App\Models\User::observe(\App\Observers\UserObserver::class);
\App\Models\Vminfo::observe(\App\Observers\VminfoObserver::class);
}
private function bootCustomValidators()

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('vminfo', function (Blueprint $table) {
$table->string('vmwVmGuestOS', 128)->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('vminfo', function (Blueprint $table) {
$table->string('vmwVmGuestOS', 128)->nullable(false)->change();
});
}
};

View File

@ -96,8 +96,7 @@ Modules.
lnms config:set discovery_modules.junose-atm-vp false
lnms config:set discovery_modules.bgp-peers true
lnms config:set discovery_modules.vlans true
lnms config:set discovery_modules.vmware-vminfo false
lnms config:set discovery_modules.libvirt-vminfo false
lnms config:set discovery_modules.vminfo false
lnms config:set discovery_modules.printer-supplies false
lnms config:set discovery_modules.ucd-diskio true
lnms config:set discovery_modules.applications false
@ -185,9 +184,7 @@ device, with history data.
`slas`: SLA detection and support.
`vmware-vminfo`: Detection of vmware guests on an ESXi host
`libvirt-vminfo`: Detection of libvirt guests.
`vminfo`: Detection of vm guests for VMware ESXi and libvert
`printer-supplies`: Toner levels support.

View File

@ -85,6 +85,7 @@ disable it for one device then you can do this within the WebUI Device
lnms config:set poller_modules.applications true
lnms config:set poller_modules.availability true
lnms config:set poller_modules.stp true
lnms config:set poller_modules.vminfo false
lnms config:set poller_modules.ntp true
lnms config:set poller_modules.services true
lnms config:set poller_modules.loadbalancers false

View File

@ -16,8 +16,6 @@ discovery_modules:
applications: false
bgp-peers: false
stp: false
vmware-vminfo: false
libvirt-vminfo: false
wireless: false
processor_stacked: true
discovery:

View File

@ -17,8 +17,7 @@ discovery_modules:
applications: true
bgp-peers: false
stp: false
vmware-vminfo: true
libvirt-vminfo: true
vminfo: true
processor_stacked: true
discovery:
-

View File

@ -25,8 +25,6 @@ poller_modules:
ipmi: false
bgp-peers: false
services: false
libvirt-vminfo: false
vmware-vminfo: false
vlans: false
arp-table: false
mef: true

View File

@ -36,8 +36,6 @@ poller_modules:
ipmi: false
bgp-peers: false
services: false
libvirt-vminfo: false
vmware-vminfo: false
vlans: false
arp-table: false
mef: false

View File

@ -16,8 +16,7 @@ discovery_modules:
applications: true
bgp-peers: false
stp: false
vmware-vminfo: true
libvirt-vminfo: true
vminfo: true
processor_stacked: true
discovery:
-

View File

@ -17,8 +17,6 @@ discovery_modules:
applications: true
bgp-peers: false
stp: false
vmware-vminfo: false
libvirt-vminfo: false
processor_stacked: true
discovery:
-

View File

@ -17,8 +17,6 @@ discovery_modules:
applications: false
bgp-peers: false
stp: false
vmware-vminfo: false
libvirt-vminfo: false
processor_stacked: true
discovery:
-

View File

@ -9,7 +9,7 @@ ifXmcbc: true
over:
- { graph: device_bits, text: 'Device Traffic' }
discovery_modules:
vmware-vminfo: true
vminfo: true
discovery:
-
sysObjectID: .1.3.6.1.4.1.6876.4.1

View File

@ -33,7 +33,6 @@ discovery_modules:
slas: false
cisco-vrf-lite: false
vrf: false
libvirt-vminfo: false
ntp: false
stp: false
printer-supplies: false

View File

@ -1,166 +0,0 @@
<?php
use Illuminate\Support\Str;
use LibreNMS\Config;
use LibreNMS\Enum\PowerState;
// FIXME should do the deletion etc in a common file perhaps? like for the sensors
// Try to discover Libvirt Virtual Machines.
if (Config::get('enable_libvirt') && $device['os'] == 'linux') {
$libvirt_vmlist = [];
$ssh_ok = 0;
$userHostname = $device['hostname'];
if (Config::has('libvirt_username')) {
$userHostname = Config::get('libvirt_username') . '@' . $userHostname;
}
foreach (Config::get('libvirt_protocols') as $method) {
if (Str::contains($method, 'qemu')) {
$uri = $method . '://' . $userHostname . '/system';
} else {
$uri = $method . '://' . $userHostname;
}
if (Str::contains($method, 'ssh') && ! $ssh_ok) {
// Check if we are using SSH if we can log in without password - without blocking the discovery
// Also automatically add the host key so discovery doesn't block on the yes/no question, and run echo so we don't get stuck in a remote shell ;-)
exec('ssh -o "StrictHostKeyChecking no" -o "PreferredAuthentications publickey" -o "IdentitiesOnly yes" ' . $userHostname . ' echo -e', $out, $ret);
if ($ret != 255) {
$ssh_ok = 1;
}
}
if ($ssh_ok || ! Str::contains($method, 'ssh')) {
// Fetch virtual machine list
unset($domlist);
exec(Config::get('virsh') . ' -rc ' . $uri . ' list', $domlist);
foreach ($domlist as $dom) {
[$dom_id] = explode(' ', trim($dom), 2);
if (is_numeric($dom_id)) {
// Fetch the Virtual Machine information.
unset($vm_info_array);
exec(Config::get('virsh') . ' -rc ' . $uri . ' dumpxml ' . $dom_id, $vm_info_array);
// Example xml:
// <domain type='kvm' id='3'>
// <name>moo.example.com</name>
// <uuid>48cf6378-6fd5-4610-0611-63dd4b31cfd6</uuid>
// <memory>1048576</memory>
// <currentMemory>1048576</currentMemory>
// <vcpu>8</vcpu>
// <os>
// <type arch='x86_64' machine='pc-0.12'>hvm</type>
// <boot dev='hd'/>
// </os>
// <features>
// <acpi/>
// (...)
// See spec at https://libvirt.org/formatdomain.html
// Convert array to string
unset($vm_info_xml);
foreach ($vm_info_array as $line) {
$vm_info_xml .= $line;
}
$xml = simplexml_load_string('<?xml version="1.0"?> ' . $vm_info_xml);
d_echo($xml);
$vmwVmDisplayName = $xml->name;
$vmwVmGuestOS = '';
// libvirt does not supply this
exec(Config::get('virsh') . ' -rc ' . $uri . ' domstate ' . $dom_id, $vm_state);
$vmwVmState = PowerState::STATES[strtolower($vm_state[0])] ?? PowerState::UNKNOWN;
unset($vm_state);
$vmwVmCpus = $xml->vcpu['current'];
if (! isset($vmwVmCpus)) {
$vmwVmCpus = $xml->vcpu;
}
$vmwVmMemSize = $xml->memory;
// Convert memory size to MiB
switch ($vmwVmMemSize['unit']) {
case 'T':
case 'TiB':
$vmwVmMemSize = $vmwVmMemSize * 1048576;
break;
case 'TB':
$vmwVmMemSize = $vmwVmMemSize * 1000000;
break;
case 'G':
case 'GiB':
$vmwVmMemSize = $vmwVmMemSize * 1024;
break;
case 'GB':
$vmwVmMemSize = $vmwVmMemSize * 1000;
break;
case 'M':
case 'MiB':
break;
case 'MB':
$vmwVmMemSize = $vmwVmMemSize * 1000000 / 1048576;
break;
case 'KB':
$vmwVmMemSize = $vmwVmMemSize / 1000;
break;
case 'b':
case 'bytes':
$vmwVmMemSize = $vmwVmMemSize / 1048576;
break;
default:
// KiB or k or no value
$vmwVmMemSize = $vmwVmMemSize / 1024;
break;
}
// Check whether the Virtual Machine is already known for this host.
$result = dbFetchRow("SELECT * FROM `vminfo` WHERE `device_id` = ? AND `vmwVmVMID` = ? AND `vm_type` = 'libvirt'", [$device['device_id'], $dom_id]);
if (empty($result)) {
$inserted_id = dbInsert(['device_id' => $device['device_id'], 'vm_type' => 'libvirt', 'vmwVmVMID' => $dom_id, 'vmwVmDisplayName' => $vmwVmDisplayName, 'vmwVmGuestOS' => $vmwVmGuestOS, 'vmwVmMemSize' => $vmwVmMemSize, 'vmwVmCpus' => $vmwVmCpus, 'vmwVmState' => $vmwVmState], 'vminfo');
echo '+';
log_event("Virtual Machine added: $vmwVmDisplayName ($vmwVmMemSize MB)", $device, 'vm', 3, $inserted_id);
} else {
if ($result['vmwVmState'] != $vmwVmState
|| $result['vmwVmDisplayName'] != $vmwVmDisplayName
|| $result['vmwVmCpus'] != $vmwVmCpus
|| $result['vmwVmGuestOS'] != $vmwVmGuestOS
|| $result['vmwVmMemSize'] != $vmwVmMemSize
) {
dbUpdate(['vmwVmState' => $vmwVmState, 'vmwVmGuestOS' => $vmwVmGuestOS, 'vmwVmDisplayName' => $vmwVmDisplayName, 'vmwVmMemSize' => $vmwVmMemSize, 'vmwVmCpus' => $vmwVmCpus], 'vminfo', "device_id=? AND vm_type='libvirt' AND vmwVmVMID=?", [$device['device_id'], $dom_id]);
echo 'U';
// FIXME eventlog
} else {
echo '.';
}
}
// Save the discovered Virtual Machine.
$libvirt_vmlist[] = $dom_id;
}//end if
}//end foreach
}//end if
// If we found VMs, don't cycle the other protocols anymore.
if (count($libvirt_vmlist)) {
break;
}
}//end foreach
// Get a list of all the known Virtual Machines for this host.
$sql = "SELECT id, vmwVmVMID, vmwVmDisplayName FROM vminfo WHERE device_id = '" . $device['device_id'] . "' AND vm_type='libvirt'";
foreach (dbFetchRows($sql) as $db_vm) {
// Delete the Virtual Machines that are removed from the host.
if (! in_array($db_vm['vmwVmVMID'], $libvirt_vmlist)) {
dbDelete('vminfo', '`id` = ?', [$db_vm['id']]);
echo '-';
log_event('Virtual Machine removed: ' . $db_vm['vmwVmDisplayName'], $device, 'vm', 4, $db_vm['id']);
}
}
echo "\n";
}//end if

View File

@ -0,0 +1,3 @@
<?php
(new \LibreNMS\Modules\Vminfo())->discover($os);

View File

@ -1,85 +0,0 @@
<?php
use LibreNMS\Enum\PowerState;
// FIXME should do the deletion etc in a common file perhaps? like for the sensors
/*
* Try to discover any Virtual Machines.
*/
if (($device['os'] == 'vmware-esxi') || ($device['os'] == 'linux')) {
/*
* Variable to hold the discovered Virtual Machines.
*/
$vmw_vmlist = [];
/*
* CONSOLE: Start the VMware discovery process.
*/
/*
* Fetch information about Virtual Machines.
*/
$oids = snmpwalk_cache_multi_oid($device, 'vmwVmTable', [], '+VMWARE-ROOT-MIB:VMWARE-VMINFO-MIB', 'vmware');
foreach ($oids as $index => $entry) {
$vmwVmDisplayName = $entry['vmwVmDisplayName'];
$vmwVmGuestOS = $entry['vmwVmGuestOS'];
$vmwVmMemSize = $entry['vmwVmMemSize'];
$vmwVmState = PowerState::STATES[strtolower($entry['vmwVmState'])] ?? PowerState::UNKNOWN;
$vmwVmCpus = $entry['vmwVmCpus'];
/*
* VMware does not return an INTEGER but a STRING of the vmwVmMemSize. This bug
* might be resolved by VMware in the future making this code obsolete.
*/
if (preg_match('/^([0-9]+) .*$/', $vmwVmMemSize, $matches)) {
$vmwVmMemSize = $matches[1];
}
/*
* Check whether the Virtual Machine is already known for this host.
*/
if (dbFetchCell("SELECT COUNT(id) FROM `vminfo` WHERE `device_id` = ? AND `vmwVmVMID` = ? AND vm_type='vmware'", [$device['device_id'], $index]) == 0) {
$vmid = dbInsert(['device_id' => $device['device_id'], 'vm_type' => 'vmware', 'vmwVmVMID' => $index, 'vmwVmDisplayName' => $vmwVmDisplayName, 'vmwVmGuestOS' => $vmwVmGuestOS, 'vmwVmMemSize' => $vmwVmMemSize, 'vmwVmCpus' => $vmwVmCpus, 'vmwVmState' => $vmwVmState], 'vminfo');
log_event($vmwVmDisplayName . " ($vmwVmMemSize GB / $vmwVmCpus vCPU) Discovered", $device, 'system', 3, $vmid);
echo '+';
// FIXME eventlog
} else {
echo '.';
}
/*
* Save the discovered Virtual Machine.
*/
$vmw_vmlist[] = $index;
}
/*
* Get a list of all the known Virtual Machines for this host.
*/
$sql = "SELECT id, vmwVmVMID, vmwVmDisplayName FROM vminfo WHERE device_id = '" . $device['device_id'] . "' AND vm_type='vmware'";
foreach (dbFetchRows($sql) as $db_vm) {
/*
* Delete the Virtual Machines that are removed from the host.
*/
if (! in_array($db_vm['vmwVmVMID'], $vmw_vmlist)) {
dbDelete('vminfo', '`id` = ?', [$db_vm['id']]);
log_event($db_vm['vmwVmDisplayName'] . ' Removed', $device, 'system', 4, $db_vm['vmwVmVMID']);
echo '-';
// FIXME eventlog
}
}
/*
* Finished discovering VMware information.
*/
echo "\n";
}//end if

View File

@ -1,78 +0,0 @@
<?php
use LibreNMS\Enum\PowerState;
/*
* CONSOLE: Start the VMware discovery process.
*/
echo 'VMware VM: ';
/*
* Get a list of all the known Virtual Machines for this host.
*/
$db_info_list = dbFetchRows('SELECT id, vmwVmVMID, vmwVmDisplayName, vmwVmGuestOS, vmwVmMemSize, vmwVmCpus, vmwVmState FROM vminfo WHERE device_id = ?', [$device['device_id']]);
$current_vminfo = snmpwalk_cache_multi_oid($device, 'vmwVmTable', [], '+VMWARE-ROOT-MIB:VMWARE-VMINFO-MIB', 'vmware');
foreach ($db_info_list as $db_info) {
/*
* Fetch the Virtual Machine information.
*
* VMWARE-VMINFO-MIB::vmwVmDisplayName.224 = STRING: My First VM
* VMWARE-VMINFO-MIB::vmwVmGuestOS.224 = STRING: windows7Server64Guest
* VMWARE-VMINFO-MIB::vmwVmMemSize.224 = INTEGER: 8192 megabytes
* VMWARE-VMINFO-MIB::vmwVmState.224 = STRING: poweredOn
* VMWARE-VMINFO-MIB::vmwVmVMID.224 = INTEGER: 224
* VMWARE-VMINFO-MIB::vmwVmCpus.224 = INTEGER: 2
*/
$vm_info = [];
$vm_info['vmwVmDisplayName'] = $current_vminfo[$db_info['vmwVmVMID']]['vmwVmDisplayName'];
$vm_info['vmwVmGuestOS'] = $current_vminfo[$db_info['vmwVmVMID']]['vmwVmGuestOS'];
$vm_info['vmwVmMemSize'] = $current_vminfo[$db_info['vmwVmVMID']]['vmwVmMemSize'];
$vm_info['vmwVmState'] = PowerState::STATES[$current_vminfo[$db_info['vmwVmVMID']]['vmwVmState']] ?? PowerState::UNKNOWN;
$vm_info['vmwVmCpus'] = $current_vminfo[$db_info['vmwVmVMID']]['vmwVmCpus'];
/*
* VMware does not return an INTEGER but a STRING of the vmwVmMemSize. This bug
* might be resolved by VMware in the future making this code absolete.
*/
if (preg_match('/^([0-9]+) .*$/', $vm_info['vmwVmMemSize'], $matches)) {
$vm_info['vmwVmMemSize'] = $matches[1];
}
/*
* If VMware Tools is not running then don't overwrite the GuesOS with the error
* message, but just leave it as it currently is.
*/
if (stristr($vm_info['vmwVmGuestOS'], 'tools not running') !== false) {
$vm_info['vmwVmGuestOS'] = $db_info['vmwVmGuestOS'];
}
/*
* Process all the VMware Virtual Machine properties.
*/
foreach ($vm_info as $property => $value) {
/*
* Check the property for any modifications.
*/
if ($vm_info[$property] != $db_info[$property]) {
// FIXME - this should loop building a query and then run the query after the loop (bad geert!)
dbUpdate([$property => $vm_info[$property]], 'vminfo', '`id` = ?', [$db_info['id']]);
if ($db_info['vmwVmDisplayName'] != null) {
log_event($db_info['vmwVmDisplayName'] . ' (' . preg_replace('/^vmwVm/', '', $property) . ') -> ' . $vm_info[$property], $device, null, 3);
}
}
}
}//end foreach
/*
* Finished discovering VMware information.
*/
echo "\n";

View File

@ -547,9 +547,6 @@ return [
'junose-atm-vp' => [
'description' => 'Junose ATM VP',
],
'libvirt-vminfo' => [
'description' => 'Libvirt VMInfo',
],
'loadbalancers' => [
'description' => 'Loadbalancers',
],
@ -602,8 +599,8 @@ return [
'vlans' => [
'description' => 'VLans',
],
'vmware-vminfo' => [
'description' => 'VMWare VMInfo',
'vminfo' => [
'description' => 'Hypervisor VM Info',
],
'vrf' => [
'description' => 'VRF',
@ -1197,6 +1194,9 @@ return [
'stp' => [
'description' => 'STP',
],
'vminfo' => [
'description' => 'Hypervisor VM Info',
],
'ntp' => [
'description' => 'NTP',
],

View File

@ -432,9 +432,6 @@ return [
'junose-atm-vp' => [
'description' => 'Junose ATM VP',
],
'libvirt-vminfo' => [
'description' => 'Libvirt VMInfo',
],
'loadbalancers' => [
'description' => 'Loadbalancers',
],
@ -489,8 +486,8 @@ return [
'vlans' => [
'description' => 'VLans',
],
'vmware-vminfo' => [
'description' => 'VMWare VMInfo',
'vminfo' => [
'description' => 'Hypervisor VM Info',
],
'vrf' => [
'description' => 'VRF',
@ -901,6 +898,9 @@ return [
'stp' => [
'description' => 'STP',
],
'vminfo' => [
'description' => 'Hypervisor VM Info',
],
'ntp' => [
'description' => 'NTP',
],

View File

@ -533,9 +533,6 @@ return [
'junose-atm-vp' => [
'description' => 'Junose ATM VP',
],
'libvirt-vminfo' => [
'description' => 'Libvirt VMInfo',
],
'loadbalancers' => [
'description' => 'Loadbalancers',
],
@ -591,8 +588,8 @@ return [
'vlans' => [
'description' => 'VLans',
],
'vmware-vminfo' => [
'description' => 'VMWare VMInfo',
'vminfo' => [
'description' => 'Hypervisor VM Info',
],
'vrf' => [
'description' => 'VRF',
@ -1167,6 +1164,9 @@ return [
'stp' => [
'description' => 'STP',
],
'vminfo' => [
'description' => 'Hypervisor VM Info',
],
'ntp' => [
'description' => 'NTP',
],

View File

@ -524,9 +524,6 @@ return [
'junose-atm-vp' => [
'description' => 'Junose ATM VP',
],
'libvirt-vminfo' => [
'description' => 'Libvirt VMInfo',
],
'loadbalancers' => [
'description' => 'Loadbalancers',
],
@ -582,8 +579,8 @@ return [
'vlans' => [
'description' => 'VLans',
],
'vmware-vminfo' => [
'description' => 'VMWare VMInfo',
'vminfo' => [
'description' => 'Hypervisor VM Info',
],
'vrf' => [
'description' => 'VRF',
@ -1158,6 +1155,9 @@ return [
'stp' => [
'description' => 'STP',
],
'vminfo' => [
'description' => 'Hypervisor VM Info',
],
'ntp' => [
'description' => 'NTP',
],

View File

@ -1297,20 +1297,13 @@
"default": true,
"type": "boolean"
},
"discovery_modules.vmware-vminfo": {
"discovery_modules.vminfo": {
"order": 350,
"group": "discovery",
"section": "discovery_modules",
"default": false,
"type": "boolean"
},
"discovery_modules.libvirt-vminfo": {
"order": 170,
"group": "discovery",
"section": "discovery_modules",
"default": false,
"type": "boolean"
},
"discovery_modules.printer-supplies": {
"order": 320,
"group": "discovery",
@ -4843,6 +4836,13 @@
"default": true,
"type": "boolean"
},
"poller_modules.vminfo": {
"order": 410,
"group": "poller",
"section": "poller_modules",
"default": false,
"type": "boolean"
},
"poller_modules.wifi": {
"order": 430,
"group": "poller",

View File

@ -2169,7 +2169,7 @@ vminfo:
- { Field: vm_type, Type: varchar(16), 'Null': false, Extra: '', Default: vmware }
- { Field: vmwVmVMID, Type: int, 'Null': false, Extra: '' }
- { Field: vmwVmDisplayName, Type: varchar(128), 'Null': false, Extra: '' }
- { Field: vmwVmGuestOS, Type: varchar(128), 'Null': false, Extra: '' }
- { Field: vmwVmGuestOS, Type: varchar(128), 'Null': true, Extra: '' }
- { Field: vmwVmMemSize, Type: int, 'Null': false, Extra: '' }
- { Field: vmwVmCpus, Type: int, 'Null': false, Extra: '' }
- { Field: vmwVmState, Type: 'smallint unsigned', 'Null': false, Extra: '' }

View File

@ -180,10 +180,7 @@
"cisco-vpdn": {
"type": "boolean"
},
"libvirt-vminfo": {
"type": "boolean"
},
"vmware-vminfo": {
"vminfo": {
"type": "boolean"
},
"vlans": {
@ -345,10 +342,7 @@
"junose-atm-vp": {
"type": "boolean"
},
"vmware-vminfo": {
"type": "boolean"
},
"libvirt-vminfo": {
"vminfo": {
"type": "boolean"
},
"mpls": {

View File

@ -1064,46 +1064,6 @@ parameters:
count: 1
path: includes/discovery/junose-atm-vp.inc.php
-
message: """
#^Call to deprecated function dbDelete\\(\\)\\:
Please use Eloquent instead; https\\://laravel\\.com/docs/eloquent\\#deleting\\-models$#
"""
count: 1
path: includes/discovery/libvirt-vminfo.inc.php
-
message: """
#^Call to deprecated function dbFetchRow\\(\\)\\:
Please use Eloquent instead; https\\://laravel\\.com/docs/eloquent$#
"""
count: 1
path: includes/discovery/libvirt-vminfo.inc.php
-
message: """
#^Call to deprecated function dbFetchRows\\(\\)\\:
Please use Eloquent instead; https\\://laravel\\.com/docs/eloquent$#
"""
count: 1
path: includes/discovery/libvirt-vminfo.inc.php
-
message: """
#^Call to deprecated function dbInsert\\(\\)\\:
Please use Eloquent instead; https\\://laravel\\.com/docs/eloquent\\#inserting\\-and\\-updating\\-models$#
"""
count: 1
path: includes/discovery/libvirt-vminfo.inc.php
-
message: """
#^Call to deprecated function dbUpdate\\(\\)\\:
Please use Eloquent instead; https\\://laravel\\.com/docs/eloquent\\#inserting\\-and\\-updating\\-models$#
"""
count: 1
path: includes/discovery/libvirt-vminfo.inc.php
-
message: """
#^Call to deprecated function dbDelete\\(\\)\\:

View File

@ -1781,5 +1781,300 @@
}
]
}
},
"vminfo": {
"discovery": {
"vminfo": [
{
"vm_type": "vmware",
"vmwVmVMID": 708,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "",
"vmwVmMemSize": 2048,
"vmwVmCpus": 2,
"vmwVmState": 0
},
{
"vm_type": "vmware",
"vmwVmVMID": 775,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "",
"vmwVmMemSize": 2048,
"vmwVmCpus": 2,
"vmwVmState": 0
},
{
"vm_type": "vmware",
"vmwVmVMID": 1644,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "",
"vmwVmMemSize": 6144,
"vmwVmCpus": 4,
"vmwVmState": 0
},
{
"vm_type": "vmware",
"vmwVmVMID": 7092,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.0-10-amd64 Debian GNU/Linux 10 (buster)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 7095,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.0-10-amd64 Debian GNU/Linux 10 (buster)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 7310,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.9.0-11-amd64 Debian GNU/Linux 9.13 (stretch)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 7642,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.0-10-amd64 Debian GNU/Linux 10 (buster)",
"vmwVmMemSize": 16384,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 7879,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "",
"vmwVmMemSize": 2048,
"vmwVmCpus": 1,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 7880,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.15.0-112-generic Ubuntu 18.04.5 LTS",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 7913,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 3.16.0-10-amd64 Debian GNU/Linux 8.11 (jessie)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8190,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.9.0-13-amd64 Debian GNU/Linux 9.13 (stretch)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8348,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.15.0-70-generic Ubuntu 18.04.3 LTS",
"vmwVmMemSize": 4096,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8371,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 3.16.0-11-amd64 Debian GNU/Linux 8.11 (jessie)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8386,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.15.0-101-generic Ubuntu 18.04.4 LTS",
"vmwVmMemSize": 4096,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8431,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.4.0-121-generic Ubuntu 16.04.4 LTS",
"vmwVmMemSize": 2048,
"vmwVmCpus": 1,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8432,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.0-9-amd64 Debian GNU/Linux 10 (buster)",
"vmwVmMemSize": 2048,
"vmwVmCpus": 1,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8453,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.0-6-amd64 Debian GNU/Linux 10 (buster)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8464,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 3.16.0-10-amd64 Debian GNU/Linux 8.11 (jessie)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8465,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.0-12-amd64 Debian GNU/Linux 10 (buster)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 1,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8484,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "",
"vmwVmMemSize": 3072,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8487,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.9.0-13-amd64 Debian GNU/Linux 9.13 (stretch)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8491,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.0-9-amd64 Debian GNU/Linux 10 (buster)",
"vmwVmMemSize": 2048,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8498,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "FreeBSD 12.1-RELEASE-p7-HBSD",
"vmwVmMemSize": 2048,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8499,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.0-8-amd64 Debian GNU/Linux 10 (buster)",
"vmwVmMemSize": 1024,
"vmwVmCpus": 1,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8502,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "FreeBSD 11.3-RELEASE-p5",
"vmwVmMemSize": 2048,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8504,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 3.16.0-4-amd64 Debian GNU/Linux 8.11 (jessie)",
"vmwVmMemSize": 4096,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8506,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 2.6.32-74-server Ubuntu 10.04.4 LTS",
"vmwVmMemSize": 2048,
"vmwVmCpus": 2,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8507,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "FreeBSD 12.1-RELEASE-p2",
"vmwVmMemSize": 4096,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8508,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Windows Server 2019, 64-bit (Build 17763)",
"vmwVmMemSize": 8192,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8510,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 5.4.0-52-generic Ubuntu 20.04.1 LTS",
"vmwVmMemSize": 4096,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8511,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.19.4-amd64-vyos Debian GNU/Linux 8.11 (jessie)",
"vmwVmMemSize": 2048,
"vmwVmCpus": 4,
"vmwVmState": 1
},
{
"vm_type": "vmware",
"vmwVmVMID": 8512,
"vmwVmDisplayName": "<private>",
"vmwVmGuestOS": "Linux 4.4.0-193-generic Ubuntu 16.04.7 LTS",
"vmwVmMemSize": 1024,
"vmwVmCpus": 1,
"vmwVmState": 1
}
]
},
"poller": "matches discovery"
}
}