Fix issue #182 by creating an uncallable managed method

VC is returning some internal managed method in 6.0. Looks like this issue
will be resolved in 6.5 server types as it will be public in 6.5. To tempoarily
workaound this issue, returning a dummy method and dummy obj instead of throwing
exception when client side can't understand the returned managed method.
This commit is contained in:
tianhao he 2016-05-20 12:24:17 -07:00
parent 55e007d4ba
commit f3245a6c33
4 changed files with 126 additions and 1 deletions

@ -734,7 +734,10 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
# val in Method val is not namespace qualified
# However, this doesn't hurt to strip out namespace
ns, name = self.GetNSAndWsdlname(data)
obj = GuessWsdlMethod(name)
try:
obj = GuessWsdlMethod(name)
except KeyError:
obj = UncallableManagedMethod(name)
elif obj is bool:
if data == "0" or data.lower() == "false":
obj = bool(False)

@ -307,6 +307,8 @@ def FormatObject(val, info=Object(name="", type=object, flags=0), indent=0):
result = "(%s) []" % itemType.__name__
elif isinstance(val, type):
result = val.__name__
elif isinstance(val, UncallableManagedMethod):
result = val.name
elif isinstance(val, ManagedMethod):
result = '%s.%s' % (val.info.type.__name__, val.info.name)
elif isinstance(val, bool):
@ -588,6 +590,15 @@ class ManagedMethod(Curry):
Curry.__init__(self, ManagedObject._InvokeMethod, 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
#
# This type must be generated dynamically because it inherits from

@ -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>

@ -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()