Merge pull request #398 from tianhao64/master
Temporarily workaround issue #182 by creating dummy managed method
This commit is contained in:
@@ -734,7 +734,10 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
|
|||||||
# val in Method val is not namespace qualified
|
# val in Method val is not namespace qualified
|
||||||
# However, this doesn't hurt to strip out namespace
|
# However, this doesn't hurt to strip out namespace
|
||||||
ns, name = self.GetNSAndWsdlname(data)
|
ns, name = self.GetNSAndWsdlname(data)
|
||||||
obj = GuessWsdlMethod(name)
|
try:
|
||||||
|
obj = GuessWsdlMethod(name)
|
||||||
|
except KeyError:
|
||||||
|
obj = UncallableManagedMethod(name)
|
||||||
elif obj is bool:
|
elif obj is bool:
|
||||||
if data == "0" or data.lower() == "false":
|
if data == "0" or data.lower() == "false":
|
||||||
obj = bool(False)
|
obj = bool(False)
|
||||||
|
@@ -307,6 +307,8 @@ def FormatObject(val, info=Object(name="", type=object, flags=0), indent=0):
|
|||||||
result = "(%s) []" % itemType.__name__
|
result = "(%s) []" % itemType.__name__
|
||||||
elif isinstance(val, type):
|
elif isinstance(val, type):
|
||||||
result = val.__name__
|
result = val.__name__
|
||||||
|
elif isinstance(val, UncallableManagedMethod):
|
||||||
|
result = val.name
|
||||||
elif isinstance(val, ManagedMethod):
|
elif isinstance(val, ManagedMethod):
|
||||||
result = '%s.%s' % (val.info.type.__name__, val.info.name)
|
result = '%s.%s' % (val.info.type.__name__, val.info.name)
|
||||||
elif isinstance(val, bool):
|
elif isinstance(val, bool):
|
||||||
@@ -588,6 +590,15 @@ class ManagedMethod(Curry):
|
|||||||
Curry.__init__(self, ManagedObject._InvokeMethod, info)
|
Curry.__init__(self, ManagedObject._InvokeMethod, info)
|
||||||
self.info = info
|
self.info = info
|
||||||
|
|
||||||
|
# Method used to represent any unknown wsdl method returned by server response.
|
||||||
|
# Server may return unknown method name due to server defects or newer version.
|
||||||
|
class UncallableManagedMethod(ManagedMethod):
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
raise Exception("Managed method {} is not available".format(self.name))
|
||||||
|
|
||||||
## Create the vmodl.MethodFault type
|
## Create the vmodl.MethodFault type
|
||||||
#
|
#
|
||||||
# This type must be generated dynamically because it inherits from
|
# This type must be generated dynamically because it inherits from
|
||||||
@@ -1038,9 +1049,15 @@ class UnknownWsdlTypeError(KeyError):
|
|||||||
# @return type if found in any one of the name spaces else throws KeyError
|
# @return type if found in any one of the name spaces else throws KeyError
|
||||||
def GuessWsdlType(name):
|
def GuessWsdlType(name):
|
||||||
with _lazyLock:
|
with _lazyLock:
|
||||||
# Because the types are lazily loaded, if some name is present
|
# Some types may exist in multiple namespaces, and returning
|
||||||
# in multiple namespaces, we will load the first type that we
|
# the wrong one will cause a deserialization error.
|
||||||
# encounter and return it.
|
# Since in python3 the order of entries in set is not deterministic,
|
||||||
|
# we will try to get the type from vim25 namespace first.
|
||||||
|
try:
|
||||||
|
return GetWsdlType(XMLNS_VMODL_BASE, name)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
for ns in _wsdlTypeMapNSs:
|
for ns in _wsdlTypeMapNSs:
|
||||||
try:
|
try:
|
||||||
return GetWsdlType(ns, name)
|
return GetWsdlType(ns, name)
|
||||||
@@ -1231,6 +1248,15 @@ def GetWsdlMethod(ns, wsdlName):
|
|||||||
# KeyError
|
# KeyError
|
||||||
def GuessWsdlMethod(name):
|
def GuessWsdlMethod(name):
|
||||||
with _lazyLock:
|
with _lazyLock:
|
||||||
|
# Some methods may exist in multiple namespaces, and returning
|
||||||
|
# the wrong one will cause a deserialization error.
|
||||||
|
# Since in python3 the order of entries in set is not deterministic,
|
||||||
|
# we will try to get the method from vim25 namespace first.
|
||||||
|
try:
|
||||||
|
return GetWsdlMethod(XMLNS_VMODL_BASE, name)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
for ns in _wsdlMethodNSs:
|
for ns in _wsdlMethodNSs:
|
||||||
try:
|
try:
|
||||||
return GetWsdlMethod(ns, name)
|
return GetWsdlMethod(ns, name)
|
||||||
|
78
tests/files/unknown_method.xml
Normal file
78
tests/files/unknown_method.xml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?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>
|
||||||
|
<ReadNextTasksResponse xmlns="urn:vim25">
|
||||||
|
<returnval>
|
||||||
|
<key>task-3996443</key>
|
||||||
|
<task type="Task">task-3996443</task>
|
||||||
|
<description>
|
||||||
|
<key>com.vmware.vdp2.task.description</key>
|
||||||
|
<arg>
|
||||||
|
<key>workOrderId</key>
|
||||||
|
<value xsi:type="xsd:string">cp.20141020150650</value>
|
||||||
|
</arg>
|
||||||
|
</description>
|
||||||
|
<descriptionId>com.vmware.vdp2.integritycheck</descriptionId>
|
||||||
|
<entity type="VirtualMachine">vm-133364</entity>
|
||||||
|
<entityName>VDP3</entityName>
|
||||||
|
<state>running</state>
|
||||||
|
<cancelled>false</cancelled>
|
||||||
|
<cancelable>true</cancelable>
|
||||||
|
<reason xsi:type="TaskReasonUser">
|
||||||
|
<userName>vmware\\sa-vdp3</userName>
|
||||||
|
</reason>
|
||||||
|
<queueTime>2014-10-20T15:09:08.789999Z</queueTime>
|
||||||
|
<startTime>2014-10-20T15:09:09.073Z</startTime>
|
||||||
|
<eventChainId>21691195</eventChainId>
|
||||||
|
</returnval>
|
||||||
|
<returnval>
|
||||||
|
<key>task-1178117</key>
|
||||||
|
<task type="Task">task-1178117</task>
|
||||||
|
<descriptionId>com.vmware.vcIntegrity.CheckNotificationTask</descriptionId>
|
||||||
|
<entity type="Folder">group-d1</entity>
|
||||||
|
<entityName>Datacenters</entityName>
|
||||||
|
<state>queued</state>
|
||||||
|
<cancelled>false</cancelled>
|
||||||
|
<cancelable>true</cancelable>
|
||||||
|
<reason xsi:type="TaskReasonSchedule">
|
||||||
|
<name>VMware vSphere Update Manager Check Notification</name>
|
||||||
|
<scheduledTask type="ScheduledTask">schedule-2</scheduledTask>
|
||||||
|
</reason>
|
||||||
|
<queueTime>2013-01-08T14:12:01.556999Z</queueTime>
|
||||||
|
<eventChainId>3410272</eventChainId>
|
||||||
|
</returnval>
|
||||||
|
<returnval>
|
||||||
|
<key>task-746590</key>
|
||||||
|
<task type="Task">task-746590</task>
|
||||||
|
<name>LeaseMapDiskRegion</name>
|
||||||
|
<descriptionId>host.DiskManager.Lease.MapDiskRegion</descriptionId>
|
||||||
|
<entity type="VirtualMachine">vm-982</entity>
|
||||||
|
<entityName>Applicure</entityName>
|
||||||
|
<state>queued</state>
|
||||||
|
<cancelled>false</cancelled>
|
||||||
|
<cancelable>false</cancelable>
|
||||||
|
<reason xsi:type="TaskReasonUser">
|
||||||
|
<userName>VMWARE\\sa-veeam1</userName>
|
||||||
|
</reason>
|
||||||
|
<queueTime>2012-09-27T12:03:03.412999Z</queueTime>
|
||||||
|
<eventChainId>2325872</eventChainId>
|
||||||
|
</returnval>
|
||||||
|
<returnval>
|
||||||
|
<key>task-56327</key>
|
||||||
|
<task type="Task">task-56327</task>
|
||||||
|
<name>LeaseMapDiskRegion</name>
|
||||||
|
<descriptionId>host.DiskManager.Lease.MapDiskRegion</descriptionId>
|
||||||
|
<entity type="VirtualMachine">vm-1010</entity>
|
||||||
|
<entityName>vCD-Oracle</entityName>
|
||||||
|
<state>queued</state>
|
||||||
|
<cancelled>false</cancelled>
|
||||||
|
<cancelable>false</cancelable>
|
||||||
|
<reason xsi:type="TaskReasonUser">
|
||||||
|
<userName>VMWARE\\sa-veeam1</userName>
|
||||||
|
</reason>
|
||||||
|
<queueTime>2012-02-27T10:56:50.656999Z</queueTime>
|
||||||
|
<eventChainId>345916</eventChainId>
|
||||||
|
</returnval>
|
||||||
|
</ReadNextTasksResponse>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>
|
33
tests/test_deserializer.py
Normal file
33
tests/test_deserializer.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# VMware vSphere Python SDK
|
||||||
|
# Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from pyVmomi import vim
|
||||||
|
from pyVmomi.SoapAdapter import SoapStubAdapter, SoapResponseDeserializer
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class DeserializerTests(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_deserialize_unknown_managed_method(self):
|
||||||
|
with open('tests/files/unknown_method.xml', 'rb') as f:
|
||||||
|
data = f.read()
|
||||||
|
stub = SoapStubAdapter(version="vim.version.version6")
|
||||||
|
deserializer = SoapResponseDeserializer(stub)
|
||||||
|
result = vim.TaskHistoryCollector._GetMethodInfo("ReadNext").result
|
||||||
|
obj = deserializer.Deserialize(data, result)
|
||||||
|
print(obj)
|
||||||
|
with self.assertRaisesRegexp(Exception, "Managed method LeaseMapDiskRegion is not available"):
|
||||||
|
obj[-1].name()
|
||||||
|
|
Reference in New Issue
Block a user