
//ui-provd: the contextual help from the external requisition screen links to this help, using the URL https://docs.opennms.com/horizon/latest/reference/provisioning/handlers/introduction.html. Ensure link in UI does not break if changing this section of docs.

[[vmware-handler]]
= VMWare Handler
:description: Learn how to use and configure the VMware adapter to pull hosts and/or virtual machines from a vCenter server into OpenNMS {page-component-title}.

The VMware adapter pulls hosts and/or virtual machines from a vCenter server into {page-component-title}.
With this adapter, you can automatically add, update, or remove nodes from your {page-component-title} based on the status of the VMware entity.
The adapter also lets {page-component-title} collect additional performance metrics directly from the VMware server based on stats stored by the hypervisor.

== Prepare VMware credentials

To allow communication between OpenNMS and VMware, you must create a user and a role for authentication and permissions.
You can either create a new local user within your vCenter server or use an account that has been defined in an external authentication system that is set up to access your vCenter instance.

=== Create a new vCenter role:
. Log into vCenter Server.
. Go to menu:Home[Administration > Roles].
. Select the built-in "Read Only" role to clone it.
. Clone the role and name the new role "OpenNMS-Access" (or another name to your preference).
. Edit the new role to add the menu:Host[CIM > CIM Interaction] permission.
. Click *OK* to save the role.

Once the role is set up, you will need to assign it to the user account.
You can either create a new user for the role or assign the role to a user from an external authentication directory on your vCenter.

=== Assign user permissions to access vCenter objects

. In your vCenter, navigate to menu:Home[Inventory > Hosts and Clusters].
. Right-click on the container to apply the permission.
** If you want {page-component-title} to import all entities, this would be the root vCenter level.
** To import only a subset of nodes, select a specific data center, cluster, or host.
. Select *Add Permission* from the right-click menu.
. Enter the name of the user account to use to connect to vCenter during the import process.
. Select the "OpenNMS-Access" role (or whatever you called it in the previous step).
. Save the role assignment and make sure to propagate to child objects, if prompted.

== Provide credentials to {page-component-title}

Now that you have configured vCenter to allow access to read objects, you must set up {page-component-title} to be able to connect to vCenter.
In the `$\{OPENNMS_HOME}/etc/vmware-config.xml` file, add a line with the hostname, user, and password to connect to your vCenter server.
If you have multiple vCenter servers, you can specify multiple `<vmware-server />` objects in this file.

[source, xml]
----
<?xml version="1.0"?>
<vmware-config>
    <vmware-server hostname="vcenter.mydomain.org" username="domain\username" password="secret"/>
</vmware-config>
----

NOTE: When specifying the username, make sure to fully qualify it with the appropriate domain name for your directory.

== Test vCenter connectivity from the Karaf shell

With `vmware-config.xml` in place, the `opennms:show-import` Karaf command can connect to vCenter using the stored credentials and print the requisition it would build, without persisting anything.
This can help verify credentials, network reachability, and TLS trust before you configure an external requisition.

From the Karaf shell:

[source, shell]
----
opennms:show-import vmware host=vcenter.mydomain.org path=
----

The `host=` value must match the `hostname` attribute on a `<vmware-server />` entry in `vmware-config.xml` byte-for-byte; the lookup is case-sensitive and does not normalize between short names and FQDNs.
The `path=` parameter is required but should be left empty for the test.

On success, the command prints the resulting requisition with some number of nodes that should be imported.
On failure, the command will print an empty requisition with zero nodes.

[NOTE]
====
If `vmware-config.xml` uses `${scv:alias:username}` and `${scv:alias:password}` references, you can supply credentials inline on the command (`username=... password=...`), which bypasses the lookup in `vmware-config.xml` entirely, or temporarily place plaintext credentials in `vmware-config.xml` for the test.
====

== Configure VMware requisition

ifeval::["{page-component-title}" == "Horizon"]
Prior to {page-component-title} 30, you set external requisitions in the `provisiond-configuration.xml` file.
This file is no longer available.
You must use the UI or the xref:development:rest/config_management.adoc#config-rest-api[config management REST API] to configure an external requisition.
endif::[]

To configure a VMware requisition, follow the steps in xref:reference:provisioning/handlers/introduction.adoc#create-req-def[Create an external requisition], but specify VMWare as the type, the host (name must match the case of the hostname entered in the `vmware-config.xml` file), username, password, schedule, and rescan behavior.

By default, the handler detects and adds all running hosts and virtual machines to the requisition.

Add additional parameters as key/value pairs in the *Advanced Options* area.

[options="header"]
[cols="1,3,1"]

|===
| Parameter
| Description
| Default

| cimTimeout
| Timeout, in milliseconds, used to test interface addresses for a reachable CIM service.
Increase this value only if you have problems discovering CIM services on host systems.
| 3000

| hostSystemServices
| Monitor services to assign to imported host systems.
Multiple values should be comma separated.
| VMware-ManagedEntity +
VMware-HostSystem +
VMwareCim-HostSystem

| importHostAll
| Imports all host systems and ignores importHostPoweredOn, importHostPoweredOff, and importHostSuspended parameters.
| false

| importHostOnly
| Imports only host systems and ignores VMs.
Cannot be true if `importVMOnly` is true.
| false

| importHostPoweredOff
| Defines if powered-off host systems should be imported.
| false

| importHostPoweredOn
| Defines if powered-on host systems should be imported.
| true

| importHostStandBy
| Defines if stand-by host systems should be imported.
| false

| importHostUnknown
| Defines if host systems with an unknown power state should be imported.
| false

| importIPv4Only
| Imports only IPv4 interfaces.
Cannot be true if `importIPv6Only` is true.
| false

| importIPv6Only
| Imports only IPv6 interfaces.
Cannot be true if `importIPv4Only` is true.
| false

| importVMAll
| Imports all virtual machines and ignores importVMPoweredOn, importVMPoweredOff, and importVMSuspended parameters.
| false

| importVMPoweredOff
| Defines if powered-off machines should be imported.
| false

| importVMPoweredOn
| Defines if powered-on machines should be imported.
| true

| importVMOnly
| Imports only virtual machines and ignores hosts.
Cannot be true if `importHostOnly` is true.
| false

| importVMSuspended
| Defines if suspended machines should be imported.
| false

| password
| Password for username to connect to your vCenter server.
|

| timeout
| VMware connection timeout, in milliseconds.
If you receive a "read timeout" error, increase this value.
| 3000

| topologyDatastores
| Add the datastores information to the VMWare topology.
| true

| topologyNetworks
| Add the network information to the VMWare topology.
If set to false, port group information will not be added to {page-component-title} topology maps.
| true

| topologyPortGroups
| Add the port groups information (distributed virtual switches) to the VMWare topology.
| false

| username
| Username to connect to your vCenter server.
|

| virtualMachineServices
| Monitor services to assign to imported virtual machines.
Multiple values should be comma separated.
| VMware-ManagedEntity +
VMware-VirtualMachine

|===

.Examples for `import-url-resource`
[source, provisiond.properties]
----
vmware://vcenter.mydomain.org?importHostPoweredOff=true
vmware://172.16.123.100/vCenterImport?key=shouldImport;value=1
vmware://172.16.123.100/vCenterImport?_shouldImport=1
vmware://172.16.123.100/vCenterImport?_shouldImport=1;username=opennms;password=secret
vmware://[2001:db8:0:8d3:0:8a2e:70:7344]?virtualMachineServices=VM-SERVICE1,VM-SERVICE2
----

NOTE: If you do not import powered-off or standby entities, they will be removed and re-added to {page-component-title} based on their power state.
This can cause their database ID to change over time.
Enabling the https://opennms.discourse.group/t/storing-data-with-foreign-sources/2057[storeByForeignSource] setting can help make sure collected metrics are kept properly.

== Provision a subset of VMware entities

To provision an arbitrary selection of VMware entities, you can specify a key-value pair to match objects that have a specific attribute in vCenter.
The key to look up is a user-defined attribute for entities being imported.
If the value provided starts with a `~`, the value will be treated as a regular expression.
Only one key-value pair can be specified per requisition.

[source, xml]
----
<requisition-def import-name="vmware-requisition"
    import-url-resource="vmware://<vcenter-host>/VCenterImport?key=OpenNMS-Import;value=yes">
----

If you need to specify several attributes, use the `_[customAttributeName]` parameter

[source, xml]
----
<requisition-def import-name="vmware-requisition"
    import-url-resource="vmware://<vcenter-host>/VCenterImport?_OpenNMS-Import=yes">
----
