Merge pull request #308 from tianhao64/master
More 6.0 related changes and bug fixes.
This commit is contained in:
commit
ef29bcf442
@ -1,13 +1,11 @@
|
|||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- "2.6"
|
|
||||||
- "2.7"
|
- "2.7"
|
||||||
- "pypy"
|
- "pypy"
|
||||||
- "3.3"
|
- "3.3"
|
||||||
- "3.4"
|
- "3.4"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2; fi
|
|
||||||
- pip install -r requirements.txt
|
- pip install -r requirements.txt
|
||||||
- pip install -r test-requirements.txt
|
- pip install -r test-requirements.txt
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import requests
|
|||||||
from requests.auth import HTTPBasicAuth
|
from requests.auth import HTTPBasicAuth
|
||||||
|
|
||||||
from pyVmomi import vim, vmodl, SoapStubAdapter, SessionOrientedStub
|
from pyVmomi import vim, vmodl, SoapStubAdapter, SessionOrientedStub
|
||||||
|
from pyVmomi.SoapAdapter import CONNECTION_POOL_IDLE_TIMEOUT_SEC
|
||||||
from pyVmomi.VmomiSupport import nsMap, versionIdMap, versionMap, IsChildVersion
|
from pyVmomi.VmomiSupport import nsMap, versionIdMap, versionMap, IsChildVersion
|
||||||
from pyVmomi.VmomiSupport import GetServiceVersions
|
from pyVmomi.VmomiSupport import GetServiceVersions
|
||||||
|
|
||||||
@ -177,7 +178,7 @@ class VimSessionOrientedStub(SessionOrientedStub):
|
|||||||
|
|
||||||
def Connect(host='localhost', port=443, user='root', pwd='',
|
def Connect(host='localhost', port=443, user='root', pwd='',
|
||||||
service="hostd", adapter="SOAP", namespace=None, path="/sdk",
|
service="hostd", adapter="SOAP", namespace=None, path="/sdk",
|
||||||
version=None, keyFile=None, certFile=None,
|
version=None, keyFile=None, certFile=None, thumbprint=None,
|
||||||
sslContext=None):
|
sslContext=None):
|
||||||
"""
|
"""
|
||||||
Connect to the specified server, login and return the service
|
Connect to the specified server, login and return the service
|
||||||
@ -212,6 +213,8 @@ def Connect(host='localhost', port=443, user='root', pwd='',
|
|||||||
@type keyFile: string
|
@type keyFile: string
|
||||||
@param certFile: ssl cert file path
|
@param certFile: ssl cert file path
|
||||||
@type certFile: string
|
@type certFile: string
|
||||||
|
@param thumbprint: host cert thumbprint
|
||||||
|
@type thumbprint: string
|
||||||
@param sslContext: SSL Context describing the various SSL options. It is only
|
@param sslContext: SSL Context describing the various SSL options. It is only
|
||||||
supported in Python 2.7.9 or higher.
|
supported in Python 2.7.9 or higher.
|
||||||
@type sslContext: SSL.Context
|
@type sslContext: SSL.Context
|
||||||
@ -233,7 +236,7 @@ def Connect(host='localhost', port=443, user='root', pwd='',
|
|||||||
elif not version:
|
elif not version:
|
||||||
version="vim.version.version6"
|
version="vim.version.version6"
|
||||||
si, stub = __Login(host, port, user, pwd, service, adapter, version, path,
|
si, stub = __Login(host, port, user, pwd, service, adapter, version, path,
|
||||||
keyFile, certFile, sslContext)
|
keyFile, certFile, thumbprint, sslContext)
|
||||||
SetSi(si)
|
SetSi(si)
|
||||||
|
|
||||||
return si
|
return si
|
||||||
@ -268,7 +271,7 @@ def GetLocalTicket(si, user):
|
|||||||
## connected service instance object.
|
## connected service instance object.
|
||||||
|
|
||||||
def __Login(host, port, user, pwd, service, adapter, version, path,
|
def __Login(host, port, user, pwd, service, adapter, version, path,
|
||||||
keyFile, certFile, sslContext):
|
keyFile, certFile, thumbprint, sslContext):
|
||||||
"""
|
"""
|
||||||
Private method that performs the actual Connect and returns a
|
Private method that performs the actual Connect and returns a
|
||||||
connected service instance object.
|
connected service instance object.
|
||||||
@ -293,6 +296,8 @@ def __Login(host, port, user, pwd, service, adapter, version, path,
|
|||||||
@type keyFile: string
|
@type keyFile: string
|
||||||
@param certFile: ssl cert file path
|
@param certFile: ssl cert file path
|
||||||
@type certFile: string
|
@type certFile: string
|
||||||
|
@param thumbprint: host cert thumbprint
|
||||||
|
@type thumbprint: string
|
||||||
@param sslContext: SSL Context describing the various SSL options. It is only
|
@param sslContext: SSL Context describing the various SSL options. It is only
|
||||||
supported in Python 2.7.9 or higher.
|
supported in Python 2.7.9 or higher.
|
||||||
@type sslContext: SSL.Context
|
@type sslContext: SSL.Context
|
||||||
@ -304,7 +309,8 @@ def __Login(host, port, user, pwd, service, adapter, version, path,
|
|||||||
|
|
||||||
# Create the SOAP stub adapter
|
# Create the SOAP stub adapter
|
||||||
stub = SoapStubAdapter(host, port, version=version, path=path,
|
stub = SoapStubAdapter(host, port, version=version, path=path,
|
||||||
certKeyFile=keyFile, certFile=certFile, sslContext=sslContext)
|
certKeyFile=keyFile, certFile=certFile,
|
||||||
|
thumbprint=thumbprint, sslContext=sslContext)
|
||||||
|
|
||||||
# Get Service instance
|
# Get Service instance
|
||||||
si = vim.ServiceInstance("ServiceInstance", stub)
|
si = vim.ServiceInstance("ServiceInstance", stub)
|
||||||
@ -555,10 +561,54 @@ def __FindSupportedVersion(protocol, server, port, path, preferredApiVersions, s
|
|||||||
return desiredVersion
|
return desiredVersion
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def SmartStubAdapter(host='localhost', port=443, path='/sdk',
|
||||||
|
url=None, sock=None, poolSize=5,
|
||||||
|
certFile=None, certKeyFile=None,
|
||||||
|
httpProxyHost=None, httpProxyPort=80, sslProxyPath=None,
|
||||||
|
thumbprint=None, cacertsFile=None, preferredApiVersions=None,
|
||||||
|
acceptCompressedResponses=True,
|
||||||
|
connectionPoolTimeout=CONNECTION_POOL_IDLE_TIMEOUT_SEC,
|
||||||
|
samlToken=None, sslContext=None):
|
||||||
|
"""
|
||||||
|
Determine the most preferred API version supported by the specified server,
|
||||||
|
then create a soap stub adapter using that version
|
||||||
|
|
||||||
|
The parameters are the same as for pyVmomi.SoapStubAdapter except for
|
||||||
|
version which is renamed to prefferedApiVersions
|
||||||
|
|
||||||
|
@param preferredApiVersions: Acceptable API version(s) (e.g. vim.version.version3)
|
||||||
|
If a list of versions is specified the versions should
|
||||||
|
be ordered from most to least preferred. If None is
|
||||||
|
specified, the list of versions support by pyVmomi will
|
||||||
|
be used.
|
||||||
|
@type preferredApiVersions: string or string list
|
||||||
|
"""
|
||||||
|
if preferredApiVersions is None:
|
||||||
|
preferredApiVersions = GetServiceVersions('vim25')
|
||||||
|
|
||||||
|
supportedVersion = __FindSupportedVersion('https' if port > 0 else 'http',
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
path,
|
||||||
|
preferredApiVersions,
|
||||||
|
sslContext)
|
||||||
|
if supportedVersion is None:
|
||||||
|
raise Exception("%s:%s is not a VIM server" % (host, port))
|
||||||
|
|
||||||
|
return SoapStubAdapter(host=host, port=port, path=path,
|
||||||
|
url=url, sock=sock, poolSize=poolSize,
|
||||||
|
certFile=certFile, certKeyFile=certKeyFile,
|
||||||
|
httpProxyHost=httpProxyHost, httpProxyPort=httpProxyPort,
|
||||||
|
sslProxyPath=sslProxyPath, thumbprint=thumbprint,
|
||||||
|
cacertsFile=cacertsFile, version=supportedVersion,
|
||||||
|
acceptCompressedResponses=acceptCompressedResponses,
|
||||||
|
connectionPoolTimeout=connectionPoolTimeout,
|
||||||
|
samlToken=samlToken, sslContext=sslContext)
|
||||||
|
|
||||||
def SmartConnect(protocol='https', host='localhost', port=443, user='root', pwd='',
|
def SmartConnect(protocol='https', host='localhost', port=443, user='root', pwd='',
|
||||||
service="hostd", path="/sdk",
|
service="hostd", path="/sdk",
|
||||||
preferredApiVersions=None, sslContext=None):
|
preferredApiVersions=None,
|
||||||
|
keyFile=None, certFile=None, thumbprint=None, sslContext=None):
|
||||||
"""
|
"""
|
||||||
Determine the most preferred API version supported by the specified server,
|
Determine the most preferred API version supported by the specified server,
|
||||||
then connect to the specified server using that API version, login and return
|
then connect to the specified server using that API version, login and return
|
||||||
@ -591,6 +641,12 @@ def SmartConnect(protocol='https', host='localhost', port=443, user='root', pwd=
|
|||||||
specified, the list of versions support by pyVmomi will
|
specified, the list of versions support by pyVmomi will
|
||||||
be used.
|
be used.
|
||||||
@type preferredApiVersions: string or string list
|
@type preferredApiVersions: string or string list
|
||||||
|
@param keyFile: ssl key file path
|
||||||
|
@type keyFile: string
|
||||||
|
@param certFile: ssl cert file path
|
||||||
|
@type certFile: string
|
||||||
|
@param thumbprint: host cert thumbprint
|
||||||
|
@type thumbprint: string
|
||||||
@param sslContext: SSL Context describing the various SSL options. It is only
|
@param sslContext: SSL Context describing the various SSL options. It is only
|
||||||
supported in Python 2.7.9 or higher.
|
supported in Python 2.7.9 or higher.
|
||||||
@type sslContext: SSL.Context
|
@type sslContext: SSL.Context
|
||||||
@ -618,6 +674,9 @@ def SmartConnect(protocol='https', host='localhost', port=443, user='root', pwd=
|
|||||||
adapter='SOAP',
|
adapter='SOAP',
|
||||||
version=supportedVersion,
|
version=supportedVersion,
|
||||||
path=path,
|
path=path,
|
||||||
|
keyFile=keyFile,
|
||||||
|
certFile=certFile,
|
||||||
|
thumbprint=thumbprint,
|
||||||
sslContext=sslContext)
|
sslContext=sslContext)
|
||||||
|
|
||||||
def OpenUrlWithBasicAuth(url, user='root', pwd=''):
|
def OpenUrlWithBasicAuth(url, user='root', pwd=''):
|
||||||
|
@ -104,6 +104,17 @@ def encode(string, encoding):
|
|||||||
return string.encode(encoding)
|
return string.encode(encoding)
|
||||||
return u(string)
|
return u(string)
|
||||||
|
|
||||||
|
## Thumbprint mismatch exception
|
||||||
|
#
|
||||||
|
class ThumbprintMismatchException(Exception):
|
||||||
|
def __init__(self, expected, actual):
|
||||||
|
Exception.__init__(self, "Server has wrong SHA1 thumbprint: %s "
|
||||||
|
"(required) != %s (server)" % (
|
||||||
|
expected, actual))
|
||||||
|
|
||||||
|
self.expected = expected
|
||||||
|
self.actual = actual
|
||||||
|
|
||||||
## Escape <, >, &
|
## Escape <, >, &
|
||||||
def XmlEscape(xmlStr):
|
def XmlEscape(xmlStr):
|
||||||
escaped = xmlStr.replace("&", "&").replace(">", ">").replace("<", "<")
|
escaped = xmlStr.replace("&", "&").replace(">", ">").replace("<", "<")
|
||||||
@ -236,7 +247,7 @@ class SoapSerializer:
|
|||||||
# @param info the field
|
# @param info the field
|
||||||
def SerializeFaultDetail(self, val, info):
|
def SerializeFaultDetail(self, val, info):
|
||||||
""" Serialize an object """
|
""" Serialize an object """
|
||||||
self._SerializeDataObject(val, info, '', self.defaultNS)
|
self._SerializeDataObject(val, info, ' xsi:typ="{1}"'.format(val._wsdlName), self.defaultNS)
|
||||||
|
|
||||||
def _NSPrefix(self, ns):
|
def _NSPrefix(self, ns):
|
||||||
""" Get xml ns prefix. self.nsMap must be set """
|
""" Get xml ns prefix. self.nsMap must be set """
|
||||||
@ -494,12 +505,7 @@ class ExpatDeserializerNSHandlers:
|
|||||||
|
|
||||||
## Get current default ns
|
## Get current default ns
|
||||||
def GetCurrDefNS(self):
|
def GetCurrDefNS(self):
|
||||||
namespaces = self.nsMap.get(None)
|
return self._GetNamespaceFromPrefix()
|
||||||
if namespaces:
|
|
||||||
ns = namespaces[-1]
|
|
||||||
else:
|
|
||||||
ns = ""
|
|
||||||
return ns
|
|
||||||
|
|
||||||
## Get namespace and wsdl name from tag
|
## Get namespace and wsdl name from tag
|
||||||
def GetNSAndWsdlname(self, tag):
|
def GetNSAndWsdlname(self, tag):
|
||||||
@ -510,9 +516,17 @@ class ExpatDeserializerNSHandlers:
|
|||||||
else:
|
else:
|
||||||
prefix, name = None, tag
|
prefix, name = None, tag
|
||||||
# Map prefix to ns
|
# Map prefix to ns
|
||||||
ns = self.nsMap[prefix][-1]
|
ns = self._GetNamespaceFromPrefix(prefix)
|
||||||
return ns, name
|
return ns, name
|
||||||
|
|
||||||
|
def _GetNamespaceFromPrefix(self, prefix = None):
|
||||||
|
namespaces = self.nsMap.get(prefix)
|
||||||
|
if namespaces:
|
||||||
|
ns = namespaces[-1]
|
||||||
|
else:
|
||||||
|
ns = ""
|
||||||
|
return ns
|
||||||
|
|
||||||
## Handle namespace begin
|
## Handle namespace begin
|
||||||
def StartNamespaceDeclHandler(self, prefix, uri):
|
def StartNamespaceDeclHandler(self, prefix, uri):
|
||||||
namespaces = self.nsMap.get(prefix)
|
namespaces = self.nsMap.get(prefix)
|
||||||
@ -930,9 +944,7 @@ try:
|
|||||||
sha1.update(derCert)
|
sha1.update(derCert)
|
||||||
sha1Digest = sha1.hexdigest().lower()
|
sha1Digest = sha1.hexdigest().lower()
|
||||||
if sha1Digest != thumbprint:
|
if sha1Digest != thumbprint:
|
||||||
raise Exception("Server has wrong SHA1 thumbprint: {0} "
|
raise ThumbprintMismatchException(thumbprint, sha1Digest)
|
||||||
"(required) != {1} (server)".format(
|
|
||||||
thumbprint, sha1Digest))
|
|
||||||
|
|
||||||
# Function used to wrap sockets with SSL
|
# Function used to wrap sockets with SSL
|
||||||
_SocketWrapper = ssl.wrap_socket
|
_SocketWrapper = ssl.wrap_socket
|
||||||
@ -963,7 +975,7 @@ except ImportError:
|
|||||||
class HTTPSConnectionWrapper(object):
|
class HTTPSConnectionWrapper(object):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
wrapped = http_client.HTTPSConnection(*args, **kwargs)
|
wrapped = http_client.HTTPSConnection(*args, **kwargs)
|
||||||
# Extract ssl.wrap_socket param unknown to httplib.HTTPConnection,
|
# Extract ssl.wrap_socket param unknown to httplib.HTTPSConnection,
|
||||||
# and push back the params in connect()
|
# and push back the params in connect()
|
||||||
self._sslArgs = {}
|
self._sslArgs = {}
|
||||||
tmpKwargs = kwargs.copy()
|
tmpKwargs = kwargs.copy()
|
||||||
@ -1028,11 +1040,13 @@ class SSLTunnelConnection(object):
|
|||||||
# @param kwargs In case caller passed in extra parameters not handled by
|
# @param kwargs In case caller passed in extra parameters not handled by
|
||||||
# SSLTunnelConnection
|
# SSLTunnelConnection
|
||||||
def __call__(self, path, key_file=None, cert_file=None, **kwargs):
|
def __call__(self, path, key_file=None, cert_file=None, **kwargs):
|
||||||
# Don't pass any keyword args that HTTPConnection won't understand.
|
# Only pass in the named arguments that HTTPConnection constructor
|
||||||
for arg in kwargs.keys():
|
# understands
|
||||||
if arg not in ("port", "strict", "timeout", "source_address"):
|
tmpKwargs = {}
|
||||||
del kwargs[arg]
|
for key in http_client.HTTPConnection.__init__.__code__.co_varnames:
|
||||||
tunnel = http_client.HTTPConnection(path, **kwargs)
|
if key in kwargs and key != 'self':
|
||||||
|
tmpKwargs[key] = kwargs[key]
|
||||||
|
tunnel = http_client.HTTPConnection(path, **tmpKwargs)
|
||||||
tunnel.request('CONNECT', self.proxyPath)
|
tunnel.request('CONNECT', self.proxyPath)
|
||||||
resp = tunnel.getresponse()
|
resp = tunnel.getresponse()
|
||||||
if resp.status != 200:
|
if resp.status != 200:
|
||||||
@ -1164,7 +1178,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
# the UnixSocketConnection ctor expects to find it -- see above
|
# the UnixSocketConnection ctor expects to find it -- see above
|
||||||
self.host = sock
|
self.host = sock
|
||||||
elif url:
|
elif url:
|
||||||
scheme, self.host, urlpath = urlparse.urlparse(url)[:3]
|
scheme, self.host, urlpath = urlparse(url)[:3]
|
||||||
# Only use the URL path if it's sensible, otherwise use the path
|
# Only use the URL path if it's sensible, otherwise use the path
|
||||||
# keyword argument as passed in.
|
# keyword argument as passed in.
|
||||||
if urlpath not in ('', '/'):
|
if urlpath not in ('', '/'):
|
||||||
@ -1219,6 +1233,20 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
self.requestModifierList = []
|
self.requestModifierList = []
|
||||||
self._acceptCompressedResponses = acceptCompressedResponses
|
self._acceptCompressedResponses = acceptCompressedResponses
|
||||||
|
|
||||||
|
# Force a socket shutdown. Before python 2.7, ssl will fail to close
|
||||||
|
# the socket (http://bugs.python.org/issue10127).
|
||||||
|
# Not making this a part of the actual _HTTPSConnection since the internals
|
||||||
|
# of the httplib.HTTP*Connection seem to pass around the descriptors and
|
||||||
|
# depend on the behavior that close() still leaves the socket semi-functional.
|
||||||
|
if sys.version_info[:2] < (2,7):
|
||||||
|
def _CloseConnection(self, conn):
|
||||||
|
# import pdb; pdb.set_trace()
|
||||||
|
if self.scheme == HTTPSConnectionWrapper and conn.sock:
|
||||||
|
conn.sock.shutdown(socket.SHUT_RDWR)
|
||||||
|
conn.close()
|
||||||
|
else:
|
||||||
|
def _CloseConnection(self, conn):
|
||||||
|
conn.close()
|
||||||
|
|
||||||
# Context modifier used to modify the SOAP request.
|
# Context modifier used to modify the SOAP request.
|
||||||
# @param func The func that takes in the serialized message and modifies the
|
# @param func The func that takes in the serialized message and modifies the
|
||||||
@ -1287,7 +1315,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
deserializer = SoapResponseDeserializer(outerStub)
|
deserializer = SoapResponseDeserializer(outerStub)
|
||||||
obj = deserializer.Deserialize(fd, info.result)
|
obj = deserializer.Deserialize(fd, info.result)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
conn.close()
|
self._CloseConnection(conn)
|
||||||
# NOTE (hartsock): This feels out of place. As a rule the lexical
|
# NOTE (hartsock): This feels out of place. As a rule the lexical
|
||||||
# context that opens a connection should also close it. However,
|
# context that opens a connection should also close it. However,
|
||||||
# in this code the connection is passed around and closed in other
|
# in this code the connection is passed around and closed in other
|
||||||
@ -1306,7 +1334,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
else:
|
else:
|
||||||
raise obj # pylint: disable-msg=E0702
|
raise obj # pylint: disable-msg=E0702
|
||||||
else:
|
else:
|
||||||
conn.close()
|
self._CloseConnection(conn)
|
||||||
raise http_client.HTTPException("{0} {1}".format(resp.status, resp.reason))
|
raise http_client.HTTPException("{0} {1}".format(resp.status, resp.reason))
|
||||||
|
|
||||||
## Clean up connection pool to throw away idle timed-out connections
|
## Clean up connection pool to throw away idle timed-out connections
|
||||||
@ -1324,7 +1352,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
break
|
break
|
||||||
|
|
||||||
for conn, _ in idleConnections:
|
for conn, _ in idleConnections:
|
||||||
conn.close()
|
self._CloseConnection(conn)
|
||||||
|
|
||||||
## Get a HTTP connection from the pool
|
## Get a HTTP connection from the pool
|
||||||
def GetConnection(self):
|
def GetConnection(self):
|
||||||
@ -1365,7 +1393,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
self.pool = []
|
self.pool = []
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
for conn, _ in oldConnections:
|
for conn, _ in oldConnections:
|
||||||
conn.close()
|
self._CloseConnection(conn)
|
||||||
|
|
||||||
## Return a HTTP connection to the pool
|
## Return a HTTP connection to the pool
|
||||||
def ReturnConnection(self, conn):
|
def ReturnConnection(self, conn):
|
||||||
@ -1380,7 +1408,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
# NOTE (hartsock): this seems to violate good coding practice in that
|
# NOTE (hartsock): this seems to violate good coding practice in that
|
||||||
# the lexical context that opens a connection should also be the
|
# the lexical context that opens a connection should also be the
|
||||||
# same context responsible for closing it.
|
# same context responsible for closing it.
|
||||||
conn.close()
|
self._CloseConnection(conn)
|
||||||
|
|
||||||
## Disable nagle on a http connections
|
## Disable nagle on a http connections
|
||||||
def DisableNagle(self, conn):
|
def DisableNagle(self, conn):
|
||||||
|
@ -465,6 +465,9 @@ class ManagedObject(object):
|
|||||||
self.__class__ == other.__class__ and \
|
self.__class__ == other.__class__ and \
|
||||||
self._serverGuid == other._serverGuid
|
self._serverGuid == other._serverGuid
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
return not(self == other)
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return str(self).__hash__()
|
return str(self).__hash__()
|
||||||
|
|
||||||
@ -1248,11 +1251,15 @@ class _BuildVersions:
|
|||||||
self._nsMap = {}
|
self._nsMap = {}
|
||||||
|
|
||||||
def Add(self, version):
|
def Add(self, version):
|
||||||
vmodlNs = version.split(".",1)[0]
|
assert '.version.' in version, 'Invalid version %s' % version
|
||||||
if not (vmodlNs in self._verMap):
|
|
||||||
self._verMap[vmodlNs] = version
|
vmodlNs = version.split(".version.", 1)[0].split(".")
|
||||||
if not (vmodlNs in self._nsMap):
|
for idx in [1, len(vmodlNs)]:
|
||||||
self._nsMap[vmodlNs] = GetVersionNamespace(version)
|
subVmodlNs = ".".join(vmodlNs[:idx])
|
||||||
|
if not (subVmodlNs in self._verMap):
|
||||||
|
self._verMap[subVmodlNs] = version
|
||||||
|
if not (subVmodlNs in self._nsMap):
|
||||||
|
self._nsMap[subVmodlNs] = GetVersionNamespace(version)
|
||||||
|
|
||||||
def Get(self, vmodlNs):
|
def Get(self, vmodlNs):
|
||||||
return self._verMap[vmodlNs]
|
return self._verMap[vmodlNs]
|
||||||
|
@ -198,7 +198,7 @@ except ImportError:
|
|||||||
pyVmomi.VmomiSupport.GetVmodlType("vmodl.DynamicData")
|
pyVmomi.VmomiSupport.GetVmodlType("vmodl.DynamicData")
|
||||||
|
|
||||||
from pyVmomi.SoapAdapter import SoapStubAdapter, StubAdapterBase, SoapCmdStubAdapter, \
|
from pyVmomi.SoapAdapter import SoapStubAdapter, StubAdapterBase, SoapCmdStubAdapter, \
|
||||||
SessionOrientedStub
|
SessionOrientedStub, ThumbprintMismatchException
|
||||||
|
|
||||||
types = pyVmomi.VmomiSupport.types
|
types = pyVmomi.VmomiSupport.types
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user