Repository: kevoreilly/CAPEv2

Issue:
AttributeError: 'vim.ResourceConfigSpec' object has no attribute 'name'
## About accounts on [capesandbox.com](https://capesandbox.com/)
* Issues isn't the way to ask for account activation. Ping capesandbox in [Twitter](https://twitter.com/capesandbox) with your username

## This is open source and you are getting __free__ support so be friendly!

# Prerequisites

Please answer the following questions for yourself before submitting an issue.

- [x] I am running the latest version
- [x] I did read the README!
- [x] I checked the documentation and found no answer
- [x] I checked to make sure that this issue has not already been filed
- [x] I'm reporting the issue to the correct repository (for multi-repository projects)
- [x] I have read and checked all configs (with all optional parts)


# Expected Behavior

Starting CAPE using `poetry run python3 cuckoo.py` should load the machinery config `vsphere`, fetch the list of VMs from our vSphere host, and power on the configured guest VMs.

# Current Behavior

After starting CAPE by running the command above, the script fails execution with the following stacktrace after fetching the list of VMs from the vSphere host:
```
Traceback (most recent call last):
  File "/opt/CAPEv2/cuckoo.py", line 140, in <module>
    cuckoo_main(max_analysis_count=args.max_analysis_count)
  File "/opt/CAPEv2/cuckoo.py", line 103, in cuckoo_main
    sched.start()
  File "/opt/CAPEv2/lib/cuckoo/core/scheduler.py", line 774, in start
    self.initialize()
  File "/opt/CAPEv2/lib/cuckoo/core/scheduler.py", line 726, in initialize
    machinery.initialize(machinery_name)
  File "/opt/CAPEv2/lib/cuckoo/common/abstracts.py", line 131, in initialize
    self._initialize_check()
  File "/opt/CAPEv2/modules/machinery/vsphere.py", line 118, in _initialize_check
    super(vSphere, self)._initialize_check()
  File "/opt/CAPEv2/lib/cuckoo/common/abstracts.py", line 206, in _initialize_check
    configured_vms = self._list()
  File "/opt/CAPEv2/modules/machinery/vsphere.py", line 163, in _list
    vmlist = [vm.summary.config.name for vm in self._get_virtual_machines(conn)]
  File "/opt/CAPEv2/modules/machinery/vsphere.py", line 163, in <listcomp>
    vmlist = [vm.summary.config.name for vm in self._get_virtual_machines(conn)]
  File "/opt/CAPEv2/modules/machinery/vsphere.py", line 202, in _get_virtual_machines
    if vm.summary.config.name:
AttributeError: 'vim.ResourceConfigSpec' object has no attribute 'name'
```

# Failure Information (for bugs)

It looks like that on our vSphere host/data center, there exist VMs without a `name` attribute as accessed by `modules/machinery/vsphere.py` via `vm.summary.config`. At least, when I debug `modules/machinery/vsphere.py` and output the list of VM objects, some of them do not include the `name` attribute.

I temporarily solved the issue by adding `if hasattr(vm.summary.config, "name"):` to line 201 in `modules/machinery/vsphere.py`. Updated code in lines 199-203: 
```
for dc, dcpath in traverseDCFolders(conn, conn.content.rootFolder.childEntity):
    for vm in traverseVMFolders(conn, dc.vmFolder.childEntity):
        if hasattr(vm.summary.config, "name"):
            self.VMtoDC[vm.summary.config.name] = dcpath
            yield vm
```
However, I don't know if this is the cleanest solution...


## Context

The CAPE host runs on Ubuntu 22.04.2 LTS, machinery in `cuckoo.conf` is `vsphere`, the latest code was pulled and all dependencies (including optional) were updated on 19th July, 2023.


Discussion:
hello, we do not maintain `vSphere` machinery, so you are more than welcome to submit PR. does your suggested solution works? 
Alright! Yes it works

Resolving patch:
diff --git a/modules/machinery/vsphere.py b/modules/machinery/vsphere.py
--- a/modules/machinery/vsphere.py
+++ b/modules/machinery/vsphere.py
@@ -198,8 +198,9 @@ def traverseVMFolders(conn, nodes):
 
         for dc, dcpath in traverseDCFolders(conn, conn.content.rootFolder.childEntity):
             for vm in traverseVMFolders(conn, dc.vmFolder.childEntity):
-                self.VMtoDC[vm.summary.config.name] = dcpath
-                yield vm
+                if hasattr(vm.summary.config, "name"):
+                    self.VMtoDC[vm.summary.config.name] = dcpath
+                    yield vm
 
     def _get_virtual_machine_by_label(self, conn, label):
         """Return the named VirtualMachine managed object"""


Test patch: