vmware / pyvmomi

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

pyVmomi.SoapAdapter.ParserError: xml document parse error #759

Open jorti opened 5 years ago

jorti commented 5 years ago

I get this error when querying the vSAN health summary. I'm using pyVmomi version 6.7.1.2018.12

Traceback (most recent call last):
  File "/usr/share/java/pycharm-community/helpers/pydev/pydevd.py", line 1741, in <module>
    main()
  File "/usr/share/java/pycharm-community/helpers/pydev/pydevd.py", line 1735, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/usr/share/java/pycharm-community/helpers/pydev/pydevd.py", line 1135, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/home/juan/devel/scripts/vmware/vsan-get-disk-health.py", line 75, in <module>
    cluster=cluster, includeObjUuids=True, fetchFromCache=True)
  File "/home/juan/.local/lib/python2.7/site-packages/pyVmomi/VmomiSupport.py", line 706, in <lambda>
    self.f(*(self.args + (obj,) + args), **kwargs)
  File "/home/juan/.local/lib/python2.7/site-packages/pyVmomi/VmomiSupport.py", line 512, in _InvokeMethod
    return self._stub.InvokeMethod(self, info, args)
  File "/home/juan/.local/lib/python2.7/site-packages/pyVmomi/SoapAdapter.py", line 1365, in InvokeMethod
    raise exc
pyVmomi.SoapAdapter.ParserError: 'xml document: <pyVmomi.SoapAdapter.GzipReader instance at 0x7facf6235b00> parse error at: line:2, col:29212'

Debugging the code I see that the response is chunked and only gets a fragment of the xml. That could be the reason of the incorrect parsing? or am I doing something wrong?

This is a fragment of the code I'm running, it fails at the line healthSummary = vhs.QueryClusterHealthSummary(...)

vc = {"host": "vcenter.example.com",
      "port": 443,
      "user": "Administrator@vsphere.local",
      "password": "123456",
      }
clusters = ["Cluster 1", "Cluster 2"]
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
si = SmartConnect(host=vc["host"],
                  user=vc["user"],
                  pwd=vc["password"],
                  port=vc["port"],
                  sslContext=context)
if not si:
    sys.exit("Could not connect to {h}".format(h=vc["host"]))
atexit.register(Disconnect, si)

# Detecting whether the host is vCenter or ESXi.
aboutInfo = si.content.about
apiVersion = vsanapiutils.GetLatestVmodlVersion(vc["host"])
if aboutInfo.apiType == 'VirtualCenter':
    majorApiVersion = aboutInfo.apiVersion.split('.')[0]
    if int(majorApiVersion) < 6:
        print('The Virtual Center with version %s (lower than 6.0) is not supported.'
              % aboutInfo.apiVersion)
        sys.exit(-1)

# Get vSAN health system from the vCenter Managed Object references.
vcMos = vsanapiutils.GetVsanVcMos(
    si._stub, context=context, version=apiVersion)

vhs = vcMos['vsan-cluster-health-system']
for c in clusters:
    cluster = getClusterInstance(c, si)
    healthSummary = vhs.QueryClusterHealthSummary(
        cluster=cluster, includeObjUuids=True, fetchFromCache=True)
    clusterStatus = healthSummary.clusterStatus

    print("Cluster %s Status: %s" % (c, clusterStatus.status))
    for hostStatus in clusterStatus.trackedHostsStatus:
        print("Host %s Status: %s" % (hostStatus.hostname, hostStatus.status))
pgbidkar commented 5 years ago

Hi @jorti Plase can you share methods vsanapiutils.GetLatestVmodlVersion, vsanapiutils.GetVsanVcMos & getClusterInstance?

jorti commented 5 years ago
apiVersion = 'vsan.version.version7'

vcMos = <type 'dict'>: {'vsan-upgrade-systemex': 'vim.VsanUpgradeSystemEx:vsan-upgrade-systemex', 'vsan-performance-manager': 'vim.cluster.VsanPerformanceManager:vsan-performance-manager', 'vsan-mass-collector': 'vim.VsanMassCollector:vsan-mass-collector', 'vsan-cluster-config-system': 'vim.cluster.VsanVcClusterConfigSystem:vsan-cluster-config-system', 'vsan-cluster-object-system': 'vim.cluster.VsanObjectSystem:vsan-cluster-object-system', 'vsan-vds-system': 'vim.vsan.VsanVdsSystem:vsan-vds-system', 'vsan-vum-system': 'vim.cluster.VsanVumSystem:vsan-vum-system', 'vsan-vc-capability-system': 'vim.cluster.VsanCapabilitySystem:vsan-vc-capability-system', 'vsan-disk-management-system': 'vim.cluster.VsanVcDiskManagementSystem:vsan-disk-management-system', 'vsan-vcsa-deployer-system': 'vim.host.VsanVcsaDeployerSystem:vsan-vcsa-deployer-system', 'vsan-stretched-cluster-system': 'vim.cluster.VsanVcStretchedClusterSystem:vsan-stretched-cluster-system', 'vsan-phonehome-system': 'vim.VsanPhoneHomeSystem:vsan-phonehome-system', 'vsan-cluster-iscsi-target-system': 'vim.cluster.VsanIscsiTargetSystem:vsan-cluster-iscsi-target-system', 'vsan-cluster-health-system': 'vim.cluster.VsanVcClusterHealthSystem:vsan-cluster-health-system', 'vsan-cluster-space-report-system': 'vim.cluster.VsanSpaceReportSystem:vsan-cluster-space-report-system'}

cluster = ClusterComputeResource: 'vim.ClusterComputeResource:domain-c113'
tony23 commented 5 years ago

Hi, I don't know if this is related, but I've also run into a problem with the VSAN Health Summary too. I had a problem using v6.0 and also after upgrading to v6.7, although the details differed slightly. I was able to track it to a problem in the XML response:

<soapenv:Envelope
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\n
    <soapenv:Body>
        <VsanQueryVcClusterHealthSummaryResponse
            xmlns=\'urn:vim25\'>
            <returnval>

The two issues I noticed are the \n just before <soapenv:Body> and the escaped single-quotes around urn:vim25. When I manually changed the XML to use double-quotes and eliminate the \n, everything worked fine.

Not 100% sure it's related but wanted to share this info in case it is.

tony23 commented 5 years ago

Just adding this: The raw XML returned from the vcenter is valid, but has an extra newline, and is inconsistent in its quoting (double vs single). It appears the \n and \' are happening during parsing:

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body><VsanQueryVcClusterHealthSummaryResponse xmlns='urn:vsan'><... remainder of XML ...>