vmware / pyvmomi

VMware vSphere API Python Bindings
Apache License 2.0
2.2k stars 767 forks source link

Cannot use VmomiSupport.VmomiJSONEncoder on ComputeResource or ClusterComputeResource. #905

Open codecando-x opened 4 years ago

codecando-x commented 4 years ago

Trying to use the VmomiJSONEncoder on ComputeResource or ClusterComputeResource objects. I have tried it two different ways but keep getting an InvalidProperty error from pyvmomi. Could you please point me in the right direction?

import atexit
import json

from pyVmomi import vim, VmomiSupport
from pyVim.connect import SmartConnectNoSSL, Disconnect

host = 'somehost'
user = 'someuser'
password = 'somepassword'
port = 443

v_session = SmartConnectNoSSL(host=host,user=user,pwd=password,port=port)
atexit.register(Disconnect, v_session)

content = v_session.RetrieveContent()

#1st WAY
container = content.rootFolder
viewType = [vim.ComputeResource] #this also does not work with vim.ClusterComputeResource
recursive = True

container_view = content.viewManager.CreateContainerView(container, viewType, recursive)
clusters = container_view.view

for cluster in clusters:
    #print(cluster)
    cluster_template = VmomiSupport.templateOf('ComputeResource')(cluster._moId, v_session._stub)
    obj_json = json.dumps(cluster_template, cls=VmomiSupport.VmomiJSONEncoder)
    print(obj_json)

container_view.Destroy()

#2ND WAY, this also does not work.
'''
children = content.rootFolder.childEntity
data = {}
for child in children:  # Iterate though DataCenters
    dc = child
    data[dc.name] = {}  # Add data Centers to data dict
    clusters = dc.hostFolder.childEntity
    for cluster in clusters:  # Iterate through the clusters 
        #print(cluster)
        #print(vars(cluster))
        #cluster_template = VmomiSupport.templateOf('ClusterComputeResource')(cluster._moId, v_session._stub)
        cluster_template = VmomiSupport.templateOf('ComputeResource')(cluster._moId, v_session._stub)
        obj_json = json.dumps(cluster_template, cls=VmomiSupport.VmomiJSONEncoder)
        print(obj_json)
'''

Error:

Traceback (most recent call last):
  File ".\test-get-cluster-info.py", line 30, in <module>
    obj_json = json.dumps(cluster_template, cls=VmomiSupport.VmomiJSONEncoder)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1008.0_x64__qbz5n2kfra8p0\lib\json\__init__.py", line 234, in dumps
    return cls(
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1008.0_x64__qbz5n2kfra8p0\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1008.0_x64__qbz5n2kfra8p0\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\someuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pyVmomi\VmomiSupport.py", line 357, in default
    result[prop.name] = getattr(obj, prop.name)
  File "C:\Users\someuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pyVmomi\VmomiSupport.py", line 700, in __call__
    return self.f(*args, **kwargs)
  File "C:\Users\someuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pyVmomi\VmomiSupport.py", line 520, in _InvokeAccessor
    return self._stub.InvokeAccessor(self, info)
  File "C:\Users\someuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pyVmomi\StubAdapterAccessorImpl.py", line 41, in InvokeAccessor
    result = self._pc.RetrievePropertiesEx(specSet=[filterSpec],
  File "C:\Users\someuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pyVmomi\VmomiSupport.py", line 706, in <lambda>
    self.f(*(self.args + (obj,) + args), **kwargs)
  File "C:\Users\someuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pyVmomi\VmomiSupport.py", line 512, in _InvokeMethod
    return self._stub.InvokeMethod(self, info, args)
  File "C:\Users\someuser\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pyVmomi\SoapAdapter.py", line 1397, in InvokeMethod
    raise obj # pylint: disable-msg=E0702
pyVmomi.VmomiSupport.InvalidProperty: (vmodl.query.InvalidProperty) {
   dynamicType = <unset>,
   dynamicProperty = (vmodl.DynamicProperty) [],
   msg = '',
   faultCause = <unset>,
   faultMessage = (vmodl.LocalizableMessage) [],
   name = 'lifecycleManaged'
}

Thanks

bishopbm1 commented 6 months ago

I see this was recently labeled as needs verification. This is still an issue that I am experiencing with the latest version of the pack.

I have found that the issue lies with the parameter:

obj: 'vim.ClusterComputeResource:<cluster_id>'

prop.name:  configManagerEnabled

Version information:

pip show pyvmomi
Name: pyvmomi
Version: 8.0.2.0.1
Summary: VMware vSphere Python SDK
Home-page: https://github.com/vmware/pyvmomi
Author: VMware, Inc.
Author-email: jhu@vmware.com
License: License :: OSI Approved :: Apache Software License
Location: /opt/stackstorm/virtualenvs/encore_systems/lib/python3.8/site-packages
Requires: six
Required-by: 

Error:

cluster_dict = json.loads(json.dumps(cluster, cls=VmomiSupport.VmomiJSONEncoder))
---------------------------------------------------------------------------
vmodl.fault.MethodNotFound                Traceback (most recent call last)
Cell In[3], line 1
----> 1 cluster_dict = json.loads(json.dumps(cluster, cls=VmomiSupport.VmomiJSONEncoder))

File /usr/lib64/python3.8/json/__init__.py:234, in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    232 if cls is None:
    233     cls = JSONEncoder
--> 234 return cls(
    235     skipkeys=skipkeys, ensure_ascii=ensure_ascii,
    236     check_circular=check_circular, allow_nan=allow_nan, indent=indent,
    237     separators=separators, default=default, sort_keys=sort_keys,
    238     **kw).encode(obj)

File /usr/lib64/python3.8/json/encoder.py:199, in JSONEncoder.encode(self, o)
    195         return encode_basestring(o)
    196 # This doesn't pass the iterator directly to ''.join() because the
    197 # exceptions aren't as detailed.  The list call should be roughly
    198 # equivalent to the PySequence_Fast that ''.join() would do.
--> 199 chunks = self.iterencode(o, _one_shot=True)
    200 if not isinstance(chunks, (list, tuple)):
    201     chunks = list(chunks)

File /usr/lib64/python3.8/json/encoder.py:257, in JSONEncoder.iterencode(self, o, _one_shot)
    252 else:
    253     _iterencode = _make_iterencode(
    254         markers, self.default, _encoder, self.indent, floatstr,
    255         self.key_separator, self.item_separator, self.sort_keys,
    256         self.skipkeys, _one_shot)
--> 257 return _iterencode(o, 0)

File /opt/stackstorm/virtualenvs/encore_systems/lib/python3.8/site-packages/pyVmomi/VmomiJSONEncoder.py:86, in VmomiJSONEncoder.default(self, obj)
     84     result['_vimtype'] = obj.__class__.__name__
     85     for prop in obj._GetPropertyList():
---> 86         result[prop.name] = getattr(obj, prop.name)
     87     return self._remove_empty_dynamic_if(result)
     88 return str(obj).strip("'")  # see VmomiSupport.FormatObject

File /opt/stackstorm/virtualenvs/encore_systems/lib/python3.8/site-packages/pyVmomi/VmomiSupport.py:592, in Curry.__call__(self, *args, **kwargs)
    590 def __call__(self, *args, **kwargs):
    591     args = self.args + args
--> 592     return self.f(*args, **kwargs)

File /opt/stackstorm/virtualenvs/encore_systems/lib/python3.8/site-packages/pyVmomi/VmomiSupport.py:397, in ManagedObject._InvokeAccessor(info, self)
    396 def _InvokeAccessor(info, self):
--> 397     return self._stub.InvokeAccessor(self, info)

File /opt/stackstorm/virtualenvs/encore_systems/lib/python3.8/site-packages/pyVmomi/StubAdapterAccessorImpl.py:58, in StubAdapterAccessorMixin.InvokeAccessor(self, mo, info)
     47         pass
     49 info = Object(name=info.name,
     50               type=ManagedObject,
     51               wsdlName="Fetch",
   (...)
     56               result=info.type,
     57               methodResult=info.type)
---> 58 return self.InvokeMethod(mo, info, (prop, ))

File /opt/stackstorm/virtualenvs/encore_systems/lib/python3.8/site-packages/pyVmomi/SoapAdapter.py:1528, in SoapStubAdapter.InvokeMethod(self, mo, info, args, outerStub)
   1526 if self._acceptCompressedResponses:
   1527     headers['Accept-Encoding'] = 'gzip, deflate'
-> 1528 req = self.SerializeRequest(mo, info, args)
   1529 for modifier in self.requestModifierList:
   1530     req = modifier(req)

File /opt/stackstorm/virtualenvs/encore_systems/lib/python3.8/site-packages/pyVmomi/SoapAdapter.py:1024, in SoapStubAdapterBase.SerializeRequest(self, mo, info, args)
   1022 def SerializeRequest(self, mo, info, args):
   1023     if not IsChildVersion(self.version, info.version):
-> 1024         raise GetVmodlType("vmodl.fault.MethodNotFound")(receiver=mo,
   1025                                                          method=info.name)
   1026     nsMap = SOAP_NSMAP.copy()
   1027     defaultNS = GetWsdlNamespace(self.version)

vmodl.fault.MethodNotFound: (vmodl.fault.MethodNotFound) {
   dynamicType = <unset>,
   dynamicProperty = (vmodl.DynamicProperty) [],
   msg = <unset>,
   faultCause = <unset>,
   faultMessage = (vmodl.LocalizableMessage) [],
   receiver = 'vim.ClusterComputeResource:domain-c1018',
   method = 'configManagerEnabled'
}

I was able to find the problem param by adding the following code to this line: https://github.com/vmware/pyvmomi/blob/master/pyVmomi/VmomiJSONEncoder.py#L86

print('obj:\n')
print(obj)
print('\n\n')
print('prop.name: \n')
print(prop.name)
print('\n\n')
result[prop.name] = getattr(obj, prop.name)

The following code can be added as a workaround for the issue while trying to make sure it only works for the cluster objects: https://github.com/vmware/pyvmomi/blob/master/pyVmomi/VmomiJSONEncoder.py#L86

if 'vim.ClusterComputeResource' in str(obj) and prop.name == 'configManagerEnabled':
    continue

result[prop.name] = getattr(obj, prop.name)