VMware
VMware vCenter server is a centralized management application that lets you manage virtual machines and ESXi hosts centrally.
IT Services · VMware
Details
| ID | VMware |
|---|---|
| Provider | Broadcom |
| Category | IT Services |
| From Version | 5.0.0 |
| Docker Image | demisto/vmware:2.0.0.10133006 |
| Supported Modules | Agentix XSIAM |
README
VMware vCenter server is a centralized management application that lets you manage virtual machines and ESXi hosts centrally.
This integration was integrated and tested with version 7.03 of VMware
Configure VMware in Cortex
| Parameter | Description | Required |
|---|---|---|
| Server URL (i.e., 192.168.0.1:30022) | The server URL of the VCenter. | True |
| Credentials | Username and password used to login into the system. | True |
| insecure | Trust any certificate (not secure). | True |
| proxy | Use system proxy settings. | False |
Use Cases
- Create and revert to snapshot.
- Get information regarding virtual machines.
- Power-on, power-off, suspend, reboot, clone, create, delete, relocate, resigster and unregister virtual machines.
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
vmware-get-vms
Returns all virtual machines on a system.
Base Command
vmware-get-vms
Input
| Argument Name | Description | Required |
|---|---|---|
| ip | List of IPs to filter VMs by. | Optional |
| hostname | Hostname to filter VMs by. | Optional |
| name | List of VM names to filter VMs by. | Optional |
| uuid | List of UUIDs to filter VMs by. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.Name | String | VM name. |
| VMWare.Template | bool | true if template, else false. |
| VMWare.Path | String | Path to VM. |
| VMWare.Guest | String | Guest full name. |
| VMWare.UUID | String | VM instance UUID. |
| VMWare.IP | String | VM IP address. |
| VMWare.State | String | VM state (i.e., poweredOn, poweredOff, suspended, HardRebooted). |
| VMWare.HostName | String | Host name of VM. |
| VMWare.MACAddress | String | MAC address of VM. |
| VMWare.SnapshotCreateDate | String | Create date of the last snapshot of the VM. |
| VMWare.SnapshotUUID | String | UUID of the last snapshot of the VM. |
| VMWare.Deleted | Boolean | If set to true, the VM was deleted. |
Command Example
!vmware-get-vms
Context Example
{
"VMWare":[
{
"Guest": "Ubuntu Linux (64-bit)",
"HostName": "ubuntu",
"IP": "192.168.100.1",
"MACAddress": "00:50:56:bc:86:ec",
"Name": "UbuntuTest",
"Path": "[datastore1] UbuntuTest/UbuntuTest.vmx",
"State": "poweredOn",
"Template": false,
"UUID": "503ca58b-0821-cf21-fb56-459e55df6d19"
}
]
}
Human Readable Output
| Name | Template | Path | Guest | UUID | IP | State | HostName | MACAddress | SnapshotCreateDate | SnapshotUUID | Deleted |
|---|---|---|---|---|---|---|---|---|---|---|---|
| VMware_vCenter_7_Integration_Test | false | [datastore1] VMware_vCenter_7_Integration_Test/VMware_vCenter_7_Integration_Test.vmx | Other 3.x or later Linux (64-bit) | 52535506-77f9-ac98-77d3-63bb537ad7d2 | 192.168.1.141 | poweredOn | localhost | 00:0c:29:d4:ca:14 | false | ||
| VMware_enhancement_test_vm | false | [datastore1] enhancement_test_3/enhancement_test_3.vmx | Other (32-bit) | 503d608e-92a1-358a-9674-2806326527f5 | poweredOn | false | |||||
| CentOS7_VMware_Integration_Test | false | [datastore1] CentOS7_VMware_Integration_Test/CentOS7_VMware_Integration_Test.vmx | CentOS 7 (64-bit) | 503dd190-3c64-493b-38ff-37db4e4ba2ab | 192.168.1.142 | poweredOn | localhost.localdomain | 00:50:56:bd:25:c4 | 2021-09-22 12:09:57.989388+00:00 | 423da02f-c7f4-3cda-a33e-1c85c10e048d | false |
| TetsVM1 | false | [datastore1] TetsVM1/TetsVM1.vmx | Other (32-bit) | 503dae8b-afc2-d253-40d5-7e25e05d86f4 | poweredOn | false | |||||
| enhancement test 2 | false | [datastore1] enhancement test 2/enhancement test 2.vmx | Other (32-bit) | 503d4b98-8a62-c31e-239a-fc9480f55d30 | poweredOff | false |
vmware-poweron
Powers on a powered-off or suspended virtual machine.
Base Command
vmware-poweron
Input
| Argument Name | Description | Required |
|---|---|---|
| vm-uuid | VM UUID of virtual machine to be powered on. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.UUID | String | VM instance UUID. |
| VMWare.State | String | VM state (i.e., poweredOn, poweredOff, suspended, HardRebooted). |
Command Example
!vmware-poweron vm-uuid="503ca58b-0821-cf21-fb56-459e55df6d19"
Context Example
{
"VMWare": {
"State": "poweredOn",
"UUID": "503ca58b-0821-cf21-fb56-459e55df6d19"
}
}
Human Readable Output
Virtual Machine was powered on successfully.
vmware-poweroff
Powers off a powered-on or suspended virtual machine.
Base Command
vmware-poweroff
Input
| Argument Name | Description | Required |
|---|---|---|
| vm-uuid | VM UUID of virtual machine to be powered on. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.UUID | String | VM instance UUID. |
| VMWare.State | String | VM state (i.e., poweredOn, poweredOff, suspended, HardRebooted). |
Command Example
!vmware-poweroff vm-uuid="503ca58b-0821-cf21-fb56-459e55df6d19"
Context Example
{
"VMWare": {
"State": "poweredOff",
"UUID": "503ca58b-0821-cf21-fb56-459e55df6d19"
}
}
Human Readable Output
Virtual Machine was powered off successfully.
vmware-hard-reboot
Reboots a powered-on virtual machine.
Base Command
vmware-hard-reboot
Input
| Argument Name | Description | Required |
|---|---|---|
| vm-uuid | VM UUID of virtual machine to reboot. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.UUID | String | VM instance UUID. |
| VMWare.State | String | VM state (i.e., poweredOn, poweredOff, suspended, HardRebooted). |
Command Example
!vmware-hard-reboot vm-uuid="503ca58b-0821-cf21-fb56-459e55df6d19"
Context Example
{
"VMWare": {
"State": "HardRebooted",
"UUID": "503ca58b-0821-cf21-fb56-459e55df6d19"
}
}
Human Readable Output
Virtual Machine was rebooted successfully.
vmware-suspend
Suspends a powered-on virtual machine.
Base Command
vmware-suspend
Input
| Argument Name | Description | Required |
|---|---|---|
| vm-uuid | VM UUID of virtual machine to be suspended. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.UUID | String | VM instance UUID. |
| VMWare.State | String | VM state (i.e., poweredOn, poweredOff, suspended, HardRebooted). |
Command Example
!vmware-suspend vm-uuid="503ca58b-0821-cf21-fb56-459e55df6d19"
Context Example
{
"VMWare": {
"State": "suspended",
"UUID": "503ca58b-0821-cf21-fb56-459e55df6d19"
}
}
Human Readable Output
Virtual Machine was suspended successfully.
vmware-soft-reboot
Issues a command to the guest operating system asking it to perform a reboot.
Base Command
vmware-soft-reboot
Input
| Argument Name | Description | Required |
|---|---|---|
| vm-uuid | VM UUID of virtual machine to reboot. | Required |
Context Output
There is no context output for this command.
Command Example
!vmware-soft-reboot vm-uuid="503ca58b-0821-cf21-fb56-459e55df6d19"
Human Readable Output
A request to reboot the guest has been sent.
vmware-create-snapshot
Creates a VM snapshot.
Base Command
vmware-create-snapshot
Input
| Argument Name | Description | Required |
|---|---|---|
| vm-uuid | VM UUID of virtual machine to take snapshot of. | Required |
| name | Snapshot name. | Optional |
| description | Snapshot description. | Optional |
| memory | Snapshot the virtual machine’s memory. Possible values are: true, false. Default is True. | Optional |
| quiesce | Quiesce guest file system (needs VMWare Tools installed). Possible values are: true, false. Default is False. | Optional |
Context Output
There is no context output for this command.
Command Example
!vmware-create-snapshot vm-uuid="503ca58b-0821-cf21-fb56-459e55df6d19" name="SnapShotName" description="A daily snapshot of VM" memory=true quiesce=false
Human Readable Output
Snapshot SnapShotName completed.
vmware-revert-snapshot
Reverts VM to snapshot.
Base Command
vmware-revert-snapshot
Input
| Argument Name | Description | Required |
|---|---|---|
| snapshot-name | Snapshot name to revert to. | Required |
| vm-uuid | VM UUID of virtual machine to revert snapshot. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.UUID | String | VM instance UUID. |
| VMWare.Snapshot | String | Name of the snapshot reverted to. |
Command Example
!vmware-revert-snapshot vm-uuid="503ca58b-0821-cf21-fb56-459e55df6d19" snapshot-name="SnapShotName"
Context Example
{
"VMWare": {
"Snapshot": "Reverted to SnapShotName",
"UUID": "503ca58b-0821-cf21-fb56-459e55df6d19"
}
}
Human Readable Output
Reverted to snapshot SnapShotName successfully.
vmware-get-events
Gets events of a VM.
Base Command
vmware-get-events
Input
| Argument Name | Description | Required |
|---|---|---|
| vm-uuid | VM UUID of virtual machine to get events of. | Required |
| event-type | Type of events to get, given in CSV (i.e., VmGuestRebootEvent,VmGuestShutdownEvent). Default is VmGuestRebootEvent,VmGuestShutdownEvent,VmPoweredOnEvent,VmPoweredOffEvent,VmSuspendedEvent. | Optional |
| start-date | Event’s start date. | Optional |
| end-date | Event’s end date. | Optional |
| user | User name. | Optional |
| limit | Number of events to return. Default is 50. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWareEvents.id | String | The id of the event. |
| VMWareEvents.Event | String | Description of the event. |
| VMWareEvents.CreatedTime | String | Creation time of the event. |
| VMWareEvents.UserName | Date | The user name of the user who triggered the event. |
Command Example
!vmware-get-events vm-uuid=525306-77f9-ac98-77d3-63bb537ad7d2 start-date="2021-12-14T00:00:00" end-date="2021-12-16T00:00:00" user="VSPHERE.TEST"
Context Example
{
"VMWareEvenet": [
{
"CreatedTime": "2021-12-15 09:38:46",
"UserName": "VSPHERE.TEST",
"Event": "Guest OS reboot for Datacenter",
"id": 99973
}
]
}
Human Readable Output
| CreatedTime | Event | UserName | id |
|---|---|---|---|
| 2021-12-15 09:38:46 | Guest OS reboot for Datacenter | VSPHERE.TEST | 999 |
vmware-change-nic-state
Changes the state of a VM NIC.
Base Command
vmware-change-nic-state
Input
| Argument Name | Description | Required |
|---|---|---|
| vm-uuid | VM UUID of virtual machine to change NIC state. | Required |
| nic-state | New state of the NIC to be changed. Possible values are: connect, disconnect, delete. | Required |
| nic-number | Number of the NIC to be changed. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.UUID | String | VM instance UUID. |
| VMWare.NICState | String | VM NIC state (i.e., connected, disconnected, delete). |
Command Example
!vmware-change-nic-state vm-uuid="503ca58b-0821-cf21-fb56-459e55df6d19" nic-state="disconnected" nic-number=1
Context Example
{
"VMWare": {
"NICState": "disconnected",
"UUID": "503ca58b-0821-cf21-fb56-459e55df6d19"
}
}
Human Readable Output
Virtual Machine’s NIC was disconnected successfully.
vmware-list-vms-by-tag
Lists all virtual storage objects attached to the tag.
Base Command
vmware-list-vms-by-tag
Input
| Argument Name | Description | Required |
|---|---|---|
| category | The category to which the tag belongs. | Required |
| tag | The tag to be queried. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWareTag.TagName | String | The tag that was queried. |
| VMwareTag.Category | String | The category to which the tag belongs. |
| VMwareTag.VM | String | VM name which the tag attached to. |
Command Example
!vmware-list-vms-by-tag category="Test Category" tag=test
Context Example
{
"VMWareTag": [
{
"Category": "Test Category",
"VM": "CentOS7_VMware_Integration_Test",
"TagName": "test"
},
{
"Category": "Test Category",
"VM": "enhancement test 2",
"TagName": "test"
},
{
"Category": "Test Category",
"VM": "VMware_enhancement_test_vm",
"TagName": "test"
}
]}
Human Readable Output
| Category | TagName | VM |
|---|---|---|
| Test Category | test | Integration_Test |
| Test Category | test | enhancement test 2 |
| Test Category | test | VMware_enhancement_test_vm |
vmware-create-vm
Creates a new virtual machine in the current folder and attaches it to the specified resource pool. This operation creates a virtual machine, instead of cloning a virtual machine from an existing one.
Base Command
vmware-create-vm
Input
| Argument Name | Description | Required |
|---|---|---|
| name | Display name of the virtual machine. | Required |
| cpu-num | Number of virtual processors in a virtual machine. | Required |
| cpu-allocation | Resource limits for CPU. | Required |
| memory | Resource limits for memory. | Required |
| virtual-memory | Size of a virtual machine’s memory, in MB. | Required |
| guestld | Short guest operating system identifier. | Optional |
| guest-os-familiy | description. | Required |
| guest-os-version | description. | Required |
| host | The target host on which the virtual machine will run. | Required |
| folder | The target folder in which the virtual machine will be located. | Required |
| pool | The resource pool to which the virtual machine will be attached. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.vName | String | VM name. |
| VMWare.Template | bool | true if template, else false. |
| VMWare.Path | String | Path to VM. |
| VMWare.Guest | String | Guest full name. |
| VMWare.UUID | String | VM instance UUID. |
| VMWare.IP | String | VM IP address. |
| VMWare.State | String | VM state (i.e., poweredOn, poweredOff, suspended, HardRebooted). |
| VMWare.HostName | String | Host name of VM. |
| VMWare.MACAddress | String | MAC address of VM. |
| VMWare.SnapshotCreateDate | String | Create date of the last snapshot of the VM. |
| VMWare.SnapshotUUID | String | UUID of the last snapshot of the VM. |
| VMWare.Deleted | Boolean | If set to true, the VM was deleted. |
Command Example
!vmware-create-vm cpu-allocation=1 cpu-num=1 guest-os-familiy=Windows guest-os-version="Microsoft Windows Server 2019 (64-bit)" host=11.11.1.111 memory=32 name="test_vm_ui" virtual-memory=32 folder="vm"
Context Example
{
"VMWare": [
{
"MACAddress": "",
"Name": "test_vm_ui",
"Deleted": false,
"IP": " ",
"HostName": " ",
"SnapshotCreateDate": "",
"UUID": "503d-11bc-834e-51a8-51b19a1b6924",
"State": "poweredOff",
"Snapshot": " ",
"Template": false,
"SnapshotUUID": "",
"Path": "[datastore1] test_vm_ui/test_vm_ui.vmx",
"Guest": "Other (32-bit)"
}
]
}
Human Readable Output
| Name | Template | Path | Guest | UUID | State | Deleted |
|---|---|---|---|---|---|---|
| test_vm_ui | false | [datastore1] test_vm_ui/test_vm_ui.vmx | Other (32-bit) | 503d9bc9-5c5a-603e-65d9-0fea7b29b9a7 | poweredOff | false |
vmware-clone-vm
Creates a clone of this virtual machine. If the virtual machine is used as a template, this method corresponds to the deploy command.
Base Command
vmware-clone-vm
Input
| Argument Name | Description | Required |
|---|---|---|
| uuid | The UUID of the VM to clone. | Required |
| name | The name of the new virtual machine. | Required |
| folder | The location of the new virtual machine. | Required |
| template | Specifies whether or not the new virtual machine should be marked as a template. | Optional |
| powerOn | Specifies whether or not the new VirtualMachine should be powered on after creation. Possible values are: true, false. Default is False. | Required |
| datastore | The datastore where the virtual machine should be located. | Optional |
| host | The target host for the virtual machine. | Optional |
| pool | The resource pool to which this virtual machine should be attached. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.Name | String | VM name. |
| VMWare.Template | bool | true if template, else false. |
| VMWare.Path | String | Path to VM. |
| VMWare.Guest | String | Guest full name. |
| VMWare.UUID | String | VM instance UUID. |
| VMWare.IP | String | VM IP address. |
| VMWare.State | String | VM state (i.e., poweredOn, poweredOff, suspended, HardRebooted). |
| VMWare.HostName | String | Host name of VM. |
| VMWare.MACAddress | String | MAC address of VM. |
| VMWare.SnapshotCreateDate | String | Create date of the last snapshot of the VM. |
| VMWare.SnapshotUUID | String | UUID of the last snapshot of the VM. |
| VMWare.Deleted | Boolean | If set to true, the VM was deleted. |
Command Example
!vmware-clone-vm folder=vm name=cloned_vm powerOn=false uuid=603e-65d9-0fea7b29b9a7
Context Example
{
"VMWare": [
{
"MACAddress": "",
"Name": "cloned_vm",
"Deleted": false,
"IP": " ",
"HostName": " ",
"SnapshotCreateDate": "",
"UUID": "e5aa-8fe8-a3faf1191395",
"State": "poweredOff",
"Template": false,
"SnapshotUUID": "",
"Path": "[datastore1] cloned_vm/cloned_vm.vmx",
"Guest": "Other (32-bit)"
}
]
}
Human Readable Output
| Name | Template | Path | Guest | UUID | State | Deleted |
|---|---|---|---|---|---|---|
| cloned_vm | false | [datastore1] cloned_vm/cloned_vm.vmx | Other (32-bit) | e5aa-8fe8-a3faf1191395 | poweredOff | false |
vmware-relocate-vm
Relocates a virtual machine to a specified location.
Base Command
vmware-relocate-vm
Input
| Argument Name | Description | Required |
|---|---|---|
| datastore | The datastore where the virtual machine should be located. If not specified, the current datastore is used. | Optional |
| folder | The folder where the virtual machine should be located. | Required |
| host | The target host for the virtual machine. | Optional |
| pool | The resource pool to which this virtual machine should be attached. | Optional |
| service | The service endpoint of vCenter where the virtual machine should be located. If not specified, the current vCenter service is used. | Optional |
| profile | Storage profile requirement for Virtual Machine’s home directory. | Optional |
| priority | The task priority. Possible values are: defaultPriority, highPriority, lowPriority. | Required |
| uuid | The UUID of the VM to relocate. | Required |
Context Output
There is no context output for this command.
Command Example
!vmware-relocate-vm folder=enhancement_check priority=defaultPriority uuid=e5aa-8fe8-a3faf1191395
Human Readable Output
Virtual Machine was relocated successfully.
vmware-delete-vm
Destroys this object, deleting its contents and removing it from its parent folder (if any).
Base Command
vmware-delete-vm
Input
| Argument Name | Description | Required |
|---|---|---|
| uuid | The UUID of the VM to delete. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| VMWare.UUID | String | VM instance UUID. |
| VMWare.Deleted | String | If set to true, the VM was deleted. |
Command Example
!vmware-delete-vm uuid=503d537f-a8d0-e5aa-8fe8-a3faf1191395
Human Readable Output
Virtual Machine was deleted successfully.
vmware-register-vm
Adds an existing virtual machine to the folder.
Base Command
vmware-register-vm
Input
| Argument Name | Description | Required |
|---|---|---|
| path | A datastore path to the virtual machine. | Required |
| name | The name to be assigned to the virtual machine. | Required |
| host | The target host on which the virtual machine will run. | Required |
| asTemplate | Flag to specify whether or not the virtual machine should be marked as a template. Possible values are: true, false. Default is False. | Optional |
| folder | Folder to register the VM to. | Required |
Context Output
There is no context output for this command.
Command Example
!vmware-register-vm path="[datastore1] test_vm_ui/test_vm_ui.vmx" folder=vm host=192.168.1.140 name=rgistered_vm asTemplate=false
Human Readable Output
Virtual Machine was registered successfully.
vmware-unregister-vm
emoves this virtual machine from the inventory without removing any of the virtual machine’s files on disk.
Base Command
vmware-unregister-vm
Input
| Argument Name | Description | Required |
|---|---|---|
| uuid | The UUID of the VM to remove. | Required |
Context Output
There is no context output for this command.
Command Example
!vmware-unregister-vm uuid=503d9bc9-5c5a-603e-65d9-0fea7b29b9a7
Human Readable Output
Virtual Machine was unregistered successfully.
Configuration parameters
url— Server URL (i.e., 192.168.0.1:30022) (required)credentials— Credentials (required)redirect_std_out— Redirect stdoutinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (17)
-
vmware-change-nic-stateChanges the state of a VM NIC.
-
vmware-clone-vmCreates a clone of this virtual machine. If the virtual machine is used as a template, this method corresponds to the deploy command.
-
vmware-create-snapshotCreates VM snapshot.
-
vmware-create-vmCreates a new virtual machine in the current folder and attaches it to the specified resource pool. This operation creates a virtual machine, rather than cloning an existing one.
-
vmware-delete-vmDestroys this object, deleting its contents and removing it from its parent folder (if any).
-
vmware-get-eventsGets events of VM.
-
vmware-get-vmsReturns all virtual machines on a system.
-
vmware-hard-rebootReboots a powered-on virtual machine.
-
vmware-list-vms-by-tagLists all virtual storage objects attached to the tag.
-
vmware-poweroffPowers off a powered-on or suspended virtual machine.
-
vmware-poweronPowers on a powered-off or suspended virtual machine.
-
vmware-register-vmAdds an existing virtual machine to the folder.
-
vmware-relocate-vmRelocates a virtual machine to a specified location.
-
vmware-revert-snapshotReverts VM to snapshot.
-
vmware-soft-rebootIssues a command to the guest operating system asking it to perform a reboot.
-
vmware-suspendSuspends a powered-on virtual machine.
-
vmware-unregister-vmRemoves this virtual machine from the inventory without removing any of the virtual machine's files on disk.
# pylint: disable=no-member # pylint: disable=no-name-in-module import ssl from io import StringIO import dateparser # type: ignore import demistomock as demisto # noqa: F401 import pyVim.task from CommonServerPython import * # noqa: F401 from pyVim.connect import Disconnect, SmartConnect from pyVmomi import vim, vmodl # type: ignore REDIRECT_STD_OUT = argToBoolean(demisto.params().get("redirect_std_out", "false")) real_demisto_info = demisto.info real_demisto_debug = demisto.debug def use_demisto_debug(msg): # pragma: no cover if REDIRECT_STD_OUT: temp = sys.stdout sys.stdout = sys.__stdout__ real_demisto_debug(msg) sys.stdout = temp else: real_demisto_debug(msg) def use_demisto_info(msg): # pragma: no cover if REDIRECT_STD_OUT: temp = sys.stdout sys.stdout = sys.__stdout__ real_demisto_info(msg) sys.stdout = temp else: real_demisto_info(msg) demisto.info = use_demisto_info # type: ignore demisto.debug = use_demisto_debug # type: ignore def parse_params(params): full_url = params["url"] url_arr = full_url.rsplit(":", 1) url = url_arr[0] port = str(url_arr[1]) user_name = params.get("credentials").get("identifier") password = params.get("credentials").get("password") return full_url, url, port, user_name, password class Client(BaseClient): def __init__(self, full_url: str, user_name: str, password: str, verify: bool = False, proxy: bool = False): self.user_name = user_name self.password = password super().__init__(base_url=f"https://{full_url}", verify=verify, proxy=proxy) demisto.debug("Getting session ID using username and password.") self.session_id = self._get_session_id() self._headers = {"vmware-api-session-id": self.session_id, "Content-Type": "application/json"} demisto.debug(f"Created new client instance using {full_url=}, {verify=}, {proxy=}.") def _get_session_id(self) -> str: """Authenticates and returns a session ID.""" # https://developer.broadcom.com/xapis/vsphere-automation-api/latest/api/session/post/ auth = (self.user_name, self.password) session_id_response = self._http_request(method="POST", url_suffix="/api/session", auth=auth, resp_type="text") demisto.debug(f"Got {session_id_response=}.") session_id = session_id_response.replace('"', "") if not session_id: raise DemistoException("Failed to obtain session ID. Check credentials and VCENTER_HOST.") return session_id def logout(self): """Closes the session and returns HTTP 204 with empty response object.""" # https://developer.broadcom.com/xapis/vsphere-automation-api/latest/api/session/delete/ self._http_request(method="DELETE", url_suffix="/api/session", resp_type="response") def get_category_id(self, category_name: str) -> str: """Get the ID of the category by its name.""" # https://developer.broadcom.com/xapis/vsphere-automation-api/latest/api/cis/tagging/category/get/ category_list_response = self._http_request(method="GET", url_suffix="/api/cis/tagging/category") # The response is a list of category IDs, not objects with names. We must iterate and get details for each. demisto.debug(f"Got {category_list_response=}.") for category_id in category_list_response: # https://developer.broadcom.com/xapis/vsphere-automation-api/latest/api/cis/tagging/category/categoryId/get/ category_details_response = self._http_request(method="GET", url_suffix=f"/api/cis/tagging/category/{category_id}") demisto.debug(f"For {category_id=}, got {category_details_response=}.") if category_details_response.get("name") == category_name: return category_id raise DemistoException(f"Category '{category_name}' not found.") def get_tag_id(self, tag_name: str, category_id: str) -> str: """Get the ID of the tag by its name, filtered by category ID.""" # https://developer.broadcom.com/xapis/vsphere-automation-api/latest/api/cis/tagging/tag__action=list-tags-for-category/post/ tag_list_response = self._http_request( method="POST", url_suffix="/api/cis/tagging/tag?action=list-tags-for-category", json_data={"category_id": category_id}, ) # The response is a list of tag IDs, not objects with names. We must iterate and get details for each. demisto.debug(f"Got {tag_list_response=}.") for tag_id in tag_list_response: # https://developer.broadcom.com/xapis/vsphere-automation-api/latest/api/cis/tagging/tag/tagId/get/ tag_details_response = self._http_request(method="GET", url_suffix=f"/api/cis/tagging/tag/{tag_id}") demisto.debug(f"For {tag_id=}, got {tag_details_response=}.") if tag_details_response.get("name") == tag_name: return tag_id raise DemistoException(f"Tag '{tag_name}' not found in the specified category.") def list_associated_objects(self, tag_id: str) -> list: """Get all objects associated with the Tag ID.""" # https://developer.broadcom.com/xapis/vsphere-automation-api/9.0/api/cis/tagging/tag-association/tagId__action=list-attached-objects/post/ tag_associated_objects_response = self._http_request( method="POST", url_suffix=f"/api/cis/tagging/tag-association/{tag_id}?action=list-attached-objects", ) demisto.debug(f"Got {tag_associated_objects_response=}.") return tag_associated_objects_response def list_vms(self, vm_ids: list) -> list: """List VMs filtered by VM IDs.""" # https://developer.broadcom.com/xapis/vsphere-automation-api/v7.0u3/vcenter/api/vcenter/vm/get/index filtered_vms_response = self._http_request(method="GET", url_suffix="/api/vcenter/vm", params={"vms": vm_ids}) demisto.debug(f"Got {filtered_vms_response=}.") return filtered_vms_response def get_limit(args): """ Args: args: Args input for command, this function uses limit, page and page_size Returns: - limit - how many items to request from AWS - IAM API. - is_manual - whether manual pagination is active (using page and page_size) - page_size - used when manual pagination is active, to bring the relevant number of results from the data. """ limit = arg_to_number(str(args.get("limit"))) if "limit" in args else None page = arg_to_number(str(args.get("page"))) if "page" in args else None page_size = arg_to_number(str(args.get("page_size"))) if "page_size" in args else None if limit is None: if page is not None and page_size is not None: if page <= 0: raise Exception("Chosen page number must be greater than 0") limit = page_size * page return limit, True, page_size else: limit = 50 return limit, False, page_size def login(url: str, port: int, user_name: str, password: str): # pragma: no cover # Preparations for SDKs connections s = ssl.SSLContext(ssl.PROTOCOL_TLS) s.verify_mode = ssl.CERT_NONE # Connect to a vCenter Server using username and password try: si = SmartConnect(host=url, user=user_name, pwd=password, port=port) except Exception: si = SmartConnect(host=url, user=user_name, pwd=password, port=port, sslContext=s) return si def logout(si): # pragma: no cover Disconnect(si) def get_vm(si, uuid): vm = si.content.searchIndex.FindByUuid(None, uuid, True, True) # type: ignore if vm is None: raise Exception("Unable to locate Virtual Machine.") return vm def search_for_obj(content, vim_type, name, folder=None, recurse=True): if folder is None: folder = content.rootFolder if not name: return None obj = None container = content.viewManager.CreateContainerView(folder, vim_type, recurse) for managed_object_ref in container.view: if managed_object_ref.name == name: obj = managed_object_ref break container.Destroy() if not obj: raise RuntimeError("Managed Object " + name + " not found.") return obj def create_vm_config_creator(host, args): spec = vim.vm.ConfigSpec() # type: ignore files = vim.vm.FileInfo() # type: ignore files.vmPathName = "[" + host.datastore[0].name + "]" + args.get("name") resource_allocation_spec = vim.ResourceAllocationInfo() # type: ignore resource_allocation_info = vim.ResourceAllocationInfo() # type: ignore resource_allocation_spec.limit = arg_to_number(args.get("cpu-allocation")) resource_allocation_info.limit = arg_to_number(args.get("memory")) spec.name = args.get("name") spec.numCPUs = arg_to_number(args.get("cpu-num")) # type: ignore[assignment] spec.cpuAllocation = resource_allocation_spec spec.memoryAllocation = resource_allocation_info spec.memoryMB = arg_to_number(args.get("virtual-memory")) spec.files = files if args.get("guest_id"): spec.guestId = args.get("guest_id") return spec def create_rellocation_locator_spec(vm, datastore): template_disks = [] disk_locators = [] # collect template disks for device in vm.config.hardware.device: if type(device).__name__ == "vim.vm.device.VirtualDisk" and hasattr(device.backing, "fileName"): template_disks.append(device) # construct locator for the disks for disk in template_disks: locator = vim.vm.RelocateSpec.DiskLocator() # type: ignore locator.diskBackingInfo = disk.backing # Backing information for the virtual disk at the destination locator.diskId = int(disk.key) locator.datastore = datastore # Destination datastore disk_locators.append(locator) return disk_locators def apply_get_vms_filters(args, vm_summery): ips = argToList(args.get("ip")) names = argToList(args.get("vm_name")) uuids = argToList(args.get("uuid")) ip = not args.get("ip") or (vm_summery.guest.ipAddress and vm_summery.guest.ipAddress in ips) hostname = not args.get("hostname") or (vm_summery.guest.hostName and vm_summery.guest.hostName == args.get("hostname")) name = not args.get("vm_name") or vm_summery.config.name in names uuid = not args.get("uuid") or vm_summery.config.instanceUuid in uuids return ip and hostname and name and uuid def get_priority(priority): if priority == "highPriority": return vim.VirtualMachine.MovePriority().highPriority # type: ignore[call-arg] # pylint: disable=no-value-for-parameter elif priority == "lowPriority": return vim.VirtualMachine.MovePriority().lowPriority # type: ignore[call-arg] # pylint: disable=no-value-for-parameter else: return vim.VirtualMachine.MovePriority().defaultPriority # type: ignore # pylint: disable=no-value-for-parameter def get_vms(si, args): data = [] content = si.RetrieveContent() # type: ignore container = content.rootFolder view_type = [vim.VirtualMachine] recursive = True container_view = content.viewManager.CreateContainerView(container, view_type, recursive) children = container_view.view limit, is_manual, page_size = get_limit(args) for child in children: summary = child.summary snapshot_create_date = datetime_to_string(child.snapshot.currentSnapshot.config.createDate) if child.snapshot else None snapshot_uuid = child.snapshot.currentSnapshot.config.uuid if child.snapshot else None if apply_get_vms_filters(args, summary): mac_address: str | None = "" try: for dev in child.config.hardware.device: if isinstance(dev, vim.vm.device.VirtualEthernetCard): mac_address = dev.macAddress break except Exception: # noqa pass data.append( { "Name": summary.config.name, "Template": summary.config.template, "Path": summary.config.vmPathName, "Guest": summary.config.guestFullName, "UUID": summary.config.instanceUuid, "IP": summary.guest.ipAddress if summary.guest.ipAddress else None, "State": summary.runtime.powerState, "HostName": summary.guest.hostName if summary.guest.hostName else None, "MACAddress": mac_address, "SnapshotCreateDate": snapshot_create_date, "SnapshotUUID": snapshot_uuid, "Deleted": False, } ) if len(data) == limit: break # Return the correct amount of data if is_manual and page_size and len(data) > page_size: data = data[-1 * page_size :] ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": data} return create_entry(data, ec) def create_entry(data, ec): return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": createContext(data, removeNull=True), "ReadableContentsFormat": formats["markdown"], "HumanReadable": tableToMarkdown( "Virtual Machines", data, headers=[ "Name", "Template", "Path", "Guest", "UUID", "IP", "State", "HostName", "MACAddress", "SnapshotCreateDate", "SnapshotUUID", "Deleted", ], removeNull=True, ) if data else "No result were found", "EntryContext": ec, } def power_on(si, uuid): vm = get_vm(si, uuid) if vm.runtime.powerState == "poweredOn": raise Exception("Virtual Machine is already powered on.") task = vm.PowerOn() while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]: # type: ignore time.sleep(1) if task.info.state == "success": ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": {"UUID": uuid, "State": "poweredOn"}} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": ec, "ReadableContentsFormat": formats["text"], "HumanReadable": "Virtual Machine was powered on successfully.", "EntryContext": ec, } elif task.info.state == "error": raise Exception("Error occurred while trying to power on Virtual Machine.") return None def power_off(si, uuid): vm = get_vm(si, uuid) if vm.runtime.powerState == "poweredOff": raise Exception("Virtual Machine is already powered off.") task = vm.PowerOff() while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]: # type: ignore time.sleep(1) if task.info.state == "success": ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": {"UUID": uuid, "State": "poweredOff"}} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": ec, "ReadableContentsFormat": formats["text"], "HumanReadable": "Virtual Machine was powered off successfully.", "EntryContext": ec, } elif task.info.state == "error": raise Exception("Error occured while trying to power off Virtual Machine.") return None def suspend(si, uuid): vm = get_vm(si, uuid) if vm.runtime.powerState == "suspended": raise Exception("Virtual Machine is already suspended.") task = vm.Suspend() while task.info.state not in [vim.TaskInfo.State.success, vim.TaskInfo.State.error]: # type: ignore time.sleep(1) if task.info.state == "success": ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": {"UUID": uuid, "State": "suspended"}} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": ec, "ReadableContentsFormat": formats["text"], "HumanReadable": "Virtual Machine was suspended successfully.", "EntryContext": ec, } elif task.info.state == "error": raise Exception("Error occured while trying to power on Virtual Machine.") return None def hard_reboot(si, uuid): vm = get_vm(si, uuid) task = vm.ResetVM_Task() wait_for_tasks(si, [task]) if task.info.state == "success": ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": {"UUID": uuid, "State": "HardRebooted"}} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": ec, "ReadableContentsFormat": formats["text"], "HumanReadable": "Virtual Machine was rebooted successfully.", "EntryContext": ec, } elif task.info.state == "error": raise Exception("Error occured while trying to reboot Virtual Machine.") return None def wait_for_tasks(si, tasks): propertyCollector = si.content.propertyCollector taskList = [str(task) for task in tasks] objSpecs = [vmodl.query.PropertyCollector.ObjectSpec(obj=task) for task in tasks] # type: ignore propertySpec = vmodl.query.PropertyCollector.PropertySpec(type=vim.Task, pathSet=[], all=True) # type: ignore filterSpec = vmodl.query.PropertyCollector.FilterSpec() filterSpec.objectSet = objSpecs filterSpec.propSet = [propertySpec] pcfilter = propertyCollector.CreateFilter(filterSpec, True) try: version, state = None, None while len(taskList): update = propertyCollector.WaitForUpdates(version) for filter_set in update.filterSet: for obj_set in filter_set.objectSet: task = obj_set.obj for change in obj_set.changeSet: if change.name == "info": state = change.val.state elif change.name == "info.state": state = change.val else: continue if str(task) not in taskList: continue if state == vim.TaskInfo.State.success: # type: ignore taskList.remove(str(task)) elif state == vim.TaskInfo.State.error: # type: ignore raise task.info.error version = update.version finally: if pcfilter: pcfilter.Destroy() def soft_reboot(si, uuid): vm = get_vm(si, uuid) vm.RebootGuest() return "A request to reboot the guest has been sent." def create_snapshot(si, args): uuid = args["vm-uuid"] vm = get_vm(si, uuid) d = str(datetime.now()) if args["memory"] == "True": mem = True else: mem = False if args["quiesce"] == "True": qui = True else: qui = False name = args.get("name", uuid + " snapshot " + d) desc = args.get("description", "Snapshot of VM UUID " + uuid + " taken on " + d) pyVim.task.WaitForTask(vm.CreateSnapshot(name=name, description=desc, memory=mem, quiesce=qui)) return "Snapshot " + name + " completed." def revert_snapshot(si, name, uuid): vm = get_vm(si, uuid) snapObj = get_snapshots(vm.snapshot.rootSnapshotList, name) if len(snapObj) == 1: snapObj = snapObj[0].snapshot pyVim.task.WaitForTask(snapObj.RevertToSnapshot_Task()) ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": {"UUID": uuid, "Snapshot": "Reverted to " + name}} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": ec, "ReadableContentsFormat": formats["text"], "HumanReadable": "Reverted to snapshot " + name + " successfully.", "EntryContext": ec, } else: return "No snapshots found with name: " + name + " on VM: " + uuid def get_snapshots(snapshots, snapname): snapObj = [] for snapshot in snapshots: if snapshot.name == snapname: snapObj.append(snapshot) else: snapObj = snapObj + get_snapshots(snapshot.childSnapshotList, snapname) return snapObj def get_events(si, args): vm = get_vm(si, args.get("vm-uuid")) hr = [] content = si.RetrieveServiceContent() # type: ignore eventManager = content.eventManager limit, is_manual, page_size = get_limit(args) time = vim.event.EventFilterSpec.ByTime() # type: ignore time.beginTime = dateparser.parse(args.get("start_date", "")) # type: ignore time.endTime = dateparser.parse(args.get("end_date", "")) # type: ignore if (args.get("start_date") and not time.beginTime) or (args.get("end_date") and not time.endTime): # type: ignore raise Exception("Dates given in a wrong format.") by_user_name = vim.event.EventFilterSpec.ByUsername() # type: ignore by_user_name.userList = argToList(args.get("user")) or None # type: ignore[assignment] filter = vim.event.EventFilterSpec.ByEntity(entity=vm, recursion="self") # type: ignore ids = args.get("event-type").split(",") filterSpec = vim.event.EventFilterSpec() filterSpec.eventTypeId = ids # type: ignore filterSpec.entity = filter # type: ignore filterSpec.time = time filterSpec.userName = by_user_name # type: ignore filterSpec.maxCount = limit # type: ignore eventRes = eventManager.QueryEvents(filterSpec) for e in eventRes: hr.append( { "id": e.key, "Event": e.fullFormattedMessage, "CreatedTime": e.createdTime.strftime("%Y-%m-%d %H:%M:%S"), "UserName": e.userName, } ) # Return the correct amount of data if is_manual and page_size and len(hr) > page_size: hr = hr[-1 * page_size :] ec = {"VMWareEvenet(val.UUID && val.UUID === obj.UUID)": hr} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": hr, "ReadableContentsFormat": formats["markdown"], "HumanReadable": tableToMarkdown("VM " + vm.summary.config.name + " Events", hr, removeNull=True) if hr else "No result were found", "EntryContext": ec, } def change_nic_state(si, args): # pragma: no cover uuid = args["vm-uuid"] new_nic_state = args["nic-state"] nic_number = args["nic-number"] vm = get_vm(si, uuid) nic_prefix_header = "Network adapter " nic_label = nic_prefix_header + str(nic_number) virtual_nic_device = None for dev in vm.config.hardware.device: if isinstance(dev, vim.vm.device.VirtualEthernetCard) and dev.deviceInfo.label == nic_label: # type: ignore virtual_nic_device = dev if not virtual_nic_device: raise Exception(f"Virtual {nic_label} could not be found.") virtual_nic_spec = vim.vm.device.VirtualDeviceSpec() # type: ignore if new_nic_state == "delete": virtual_nic_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.remove # type: ignore else: virtual_nic_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit # type: ignore virtual_nic_spec.device = virtual_nic_device virtual_nic_spec.device.key = virtual_nic_device.key virtual_nic_spec.device.macAddress = virtual_nic_device.macAddress virtual_nic_spec.device.backing = virtual_nic_device.backing virtual_nic_spec.device.wakeOnLanEnabled = virtual_nic_device.wakeOnLanEnabled connectable = vim.vm.device.VirtualDevice.ConnectInfo() # type: ignore if new_nic_state == "connect": connectable.connected = True connectable.startConnected = True elif new_nic_state == "disconnect": connectable.connected = False connectable.startConnected = False else: connectable = virtual_nic_device.connectable # type: ignore[assignment] virtual_nic_spec.device.connectable = connectable dev_changes = [] dev_changes.append(virtual_nic_spec) spec = vim.vm.ConfigSpec() # type: ignore spec.deviceChange = dev_changes task = vm.ReconfigVM_Task(spec=spec) wait_for_tasks(si, [task]) res_new_nic_state = (new_nic_state + "ed").replace("eed", "ed") if task.info.state == "success": ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": {"UUID": uuid, "NICState": res_new_nic_state}} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": ec, "ReadableContentsFormat": formats["text"], "HumanReadable": f"Virtual Machine's NIC was {res_new_nic_state} successfully.", "EntryContext": ec, } elif task.info.state == "error": raise Exception("Error occurred while trying to clone VM.") return None def list_vms_by_tag(client: Client, args: dict) -> CommandResults: """Lists VMs by tag using the REST API Client.""" category_name = args["category"] tag_name = args["tag"] # STEP 1 - Get category ID by category name category_id = client.get_category_id(category_name) demisto.debug(f"Got {category_id=} using {category_name=}.") # STEP 2 - Get tag ID by tag name and category ID tag_id = client.get_tag_id(tag_name, category_id) demisto.debug(f"Got {tag_id=} using {tag_name=} and {category_id=}.") # STEP 3 - Get objects associated with tag ID associated_objects = client.list_associated_objects(tag_id) demisto.debug(f"Got {len(associated_objects)} objects associated with {tag_id=}.") # STEP 4 - Filter VMs for list of associated objects vm_ids = [vm.get("id") for vm in associated_objects if vm.get("type") == "VirtualMachine"] demisto.debug(f"Got {len(vm_ids)} VM IDs associated with {tag_id=}.") # STEP 5 - Get VM names by VM IDs associated_vms = client.list_vms(vm_ids) if vm_ids else [] demisto.debug(f"Got {len(associated_vms)} VMs associated with {tag_id=}.") context_output = [{"VM": vm.get("name"), "TagName": tag_name, "Category": category_name} for vm in associated_vms] return CommandResults( readable_output=tableToMarkdown(f"VMs with category: {category_name!r} and tag: {tag_name!r}", associated_vms), outputs=context_output, outputs_prefix="VMwareTag", outputs_key_field=["VM", "TagName", "Category"], ) def create_vm(si, args): content = si.RetrieveContent() folder = search_for_obj(content, [vim.Folder], args.get("folder")) host = search_for_obj(content, [vim.HostSystem], args.get("host")) if not host: raise Exception("The host provided is not valid.") pool = host.parent.resourcePool spec = create_vm_config_creator(host, args) task = folder.CreateVM_Task(config=spec, pool=pool, host=host) wait_for_tasks(si, [task]) if task.info.state == "success": mac_address: str | None = "" summary = task.info.result.summary try: for dev in task.info.result.config.hardware.device: if isinstance(dev, vim.vm.device.VirtualEthernetCard): mac_address = dev.macAddress break except Exception: # noqa pass data = { "Name": summary.config.name, "Template": summary.config.template, "Path": summary.config.vmPathName, "Guest": summary.config.guestFullName, "UUID": summary.config.instanceUuid, "IP": summary.guest.ipAddress if summary.guest.ipAddress else None, "State": summary.runtime.powerState, "HostName": summary.guest.hostName if summary.guest.hostName else None, "MACAddress": mac_address, "Snapshot": task.info.result.snapshot.currentSnapshot if task.info.result.snapshot else None, "SnapshotCreateDate": "", "SnapshotUUID": "", "Deleted": False, } data = createContext(data, removeNull=True) ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": data} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": data, "ReadableContentsFormat": formats["markdown"], "HumanReadable": tableToMarkdown( "Virtual Machine", data, headers=[ "Name", "Template", "Path", "Guest", "UUID", "IP", "State", "HostName", "MACAddress", "SnapshotCreateDate", "SnapshotUUID", "Deleted", ], removeNull=True, ), "EntryContext": ec, } elif task.info.state == "error": raise Exception("Error occurred while trying to create a VM.") return None def clone_vm(si, args): vm = get_vm(si, args.get("uuid")) content = si.RetrieveContent() spec = vim.vm.CloneSpec() # type: ignore relocate_spec = vim.vm.RelocateSpec() # type: ignore relocate_spec.datastore = search_for_obj(content, [vim.Datastore], args.get("datastore")) relocate_spec.host = search_for_obj(content, [vim.HostSystem], args.get("host")) relocate_spec.pool = search_for_obj(content, [vim.ResourcePool], args.get("pool")) # type: ignore spec.location = relocate_spec spec.template = argToBoolean(args.get("template", False)) spec.powerOn = argToBoolean(args.get("powerOn")) folder = search_for_obj(content, [vim.Folder], args.get("folder")) task = vm.CloneVM_Task(folder=folder, name=args.get("name"), spec=spec) wait_for_tasks(si, [task]) if task.info.state == "success": mac_address: str | None = "" summary = task.info.result.summary try: for dev in task.info.result.config.hardware.device: if isinstance(dev, vim.vm.device.VirtualEthernetCard): mac_address = dev.macAddress break except Exception: # noqa pass data = { "Name": summary.config.name, "Template": summary.config.template, "Path": summary.config.vmPathName, "Guest": summary.config.guestFullName, "UUID": summary.config.instanceUuid, "IP": summary.guest.ipAddress if summary.guest.ipAddress else None, "State": summary.runtime.powerState, "HostName": summary.guest.hostName if summary.guest.hostName else None, "MACAddress": mac_address, "SnapshotCreateDate": "", "SnapshotUUID": "", "Deleted": False, } data = createContext(data, removeNull=True) ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": data} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": data, "ReadableContentsFormat": formats["markdown"], "HumanReadable": tableToMarkdown( "Virtual Machine", data, headers=[ "Name", "Template", "Path", "Guest", "UUID", "IP", "State", "HostName", "MACAddress", "SnapshotCreateDate", "SnapshotUUID", "Deleted", ], removeNull=True, ), "EntryContext": ec, } elif task.info.state == "error": raise Exception("Error occurred while trying to clone VM.") return None def relocate_vm(si, args): content = si.RetrieveContent() vm = get_vm(si, args.get("uuid")) priority = get_priority(args.get("priority")) spec = vim.VirtualMachineRelocateSpec() # type: ignore spec.folder = search_for_obj(content, [vim.Folder], args.get("folder")) spec.host = search_for_obj(content, [vim.HostSystem], args.get("host")) spec.pool = search_for_obj(content, [vim.ResourcePool], args.get("pool")) # type: ignore datastore = search_for_obj(content, [vim.Datastore], args.get("datastore")) if datastore: spec.datastore = datastore spec.disks = create_rellocation_locator_spec(vm, datastore) task = vm.RelocateVM_Task(spec, priority) wait_for_tasks(si, [task]) if task.info.state == "success": return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": {}, "ReadableContentsFormat": formats["text"], "HumanReadable": "Virtual Machine was relocated successfully.", "EntryContext": {}, } elif task.info.state == "error": raise Exception("Error occurred while trying to relocate VM.") return None def delete_vm(si, args): vm = get_vm(si, args.get("uuid")) if vm.runtime.powerState == "poweredOn": raise Exception("Virtual Machine should be powered off before deleting.") task = vm.Destroy_Task() wait_for_tasks(si, [task]) if task.info.state == "success": data = {"UUID": args.get("uuid"), "Deleted": True} ec = {"VMWare(val.UUID && val.UUID === obj.UUID)": data} return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": {}, "ReadableContentsFormat": formats["text"], "HumanReadable": "Virtual Machine was deleted successfully.", "EntryContext": ec, } elif task.info.state == "error": raise Exception("Error occurred while trying to delete VM.") return None def register_vm(si, args): content = si.RetrieveContent() folder = search_for_obj(content, [vim.Folder], args.get("folder")) host = search_for_obj(content, [vim.HostSystem], args.get("host")) pool = host.parent.resourcePool task = folder.RegisterVM_Task( path=args.get("path"), name=args.get("name"), asTemplate=argToBoolean(args.get("as_template")), pool=pool, host=host ) wait_for_tasks(si, [task]) if task.info.state == "success": return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": {}, "ReadableContentsFormat": formats["text"], "HumanReadable": "Virtual Machine was registered successfully.", "EntryContext": {}, } elif task.info.state == "error": raise Exception("Error occurred while trying to register VM.") return None def unregister_vm(si, args): vm = get_vm(si, args.get("uuid")) vm.UnregisterVM() return { "ContentsFormat": formats["json"], "Type": entryTypes["note"], "Contents": {}, "ReadableContentsFormat": formats["text"], "HumanReadable": "Virtual Machine was unregistered successfully.", "EntryContext": {}, } def test_module(si): get_vms(si, {"limit": "1"}) return "ok" def main(): # pragma: no cover params = demisto.params() command = demisto.command() args = demisto.args() full_url, url, port, user_name, password = parse_params(params) verify = not params.get("insecure", False) proxy = params.get("proxy", False) if REDIRECT_STD_OUT: sys.stdout = StringIO() res = [] si = None client = None result: Any = None try: si = login(url, port, user_name, password) if command == "test-module": result = test_module(si) if command == "vmware-get-vms": result = get_vms(si, args) if command == "vmware-poweron": result = power_on(si, args["vm-uuid"]) if command == "vmware-poweroff": result = power_off(si, args["vm-uuid"]) if command == "vmware-hard-reboot": result = hard_reboot(si, args["vm-uuid"]) if command == "vmware-suspend": result = suspend(si, args["vm-uuid"]) if command == "vmware-soft-reboot": result = soft_reboot(si, args["vm-uuid"]) if command == "vmware-create-snapshot": result = create_snapshot(si, args) if command == "vmware-revert-snapshot": result = revert_snapshot(si, args["snapshot-name"], args["vm-uuid"]) if command == "vmware-get-events": result = get_events(si, args) if command == "vmware-change-nic-state": result = change_nic_state(si, args) if command == "vmware-list-vms-by-tag": client = Client(full_url, user_name, password, verify=verify, proxy=proxy) return_results(list_vms_by_tag(client, args)) if command == "vmware-create-vm": result = create_vm(si, args) if command == "vmware-clone-vm": result = clone_vm(si, args) if command == "vmware-relocate-vm": result = relocate_vm(si, args) if command == "vmware-delete-vm": result = delete_vm(si, args) if command == "vmware-register-vm": result = register_vm(si, args) if command == "vmware-unregister-vm": result = unregister_vm(si, args) if result is not None: res.append(result) except Exception as ex: if hasattr(ex, "msg") and ex.msg: # type: ignore message = ex.msg # type: ignore else: message = ex res.append({"Type": entryTypes["error"], "ContentsFormat": formats["text"], "Contents": str(message)}) # type: ignore try: logout(si) if client: client.logout() except Exception as ex: res.append( { # type: ignore "Type": entryTypes["error"], "ContentsFormat": formats["text"], "Contents": "Logout failed. " + str(ex), } ) sys.stdout = sys.__stdout__ demisto.results(res) if __name__ in ("__main__", "__builtin__", "builtins"): main()