@@ -3,6 +3,8 @@ python:
|
|||||||
- "2.6"
|
- "2.6"
|
||||||
- "2.7"
|
- "2.7"
|
||||||
- "pypy"
|
- "pypy"
|
||||||
|
- "3.3"
|
||||||
|
- "3.4"
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2; fi
|
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2; fi
|
||||||
@@ -10,6 +12,6 @@ before_install:
|
|||||||
- pip install -r test-requirements.txt
|
- pip install -r test-requirements.txt
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- python setup.py -q install
|
- python setup.py install
|
||||||
|
|
||||||
script: python setup.py test
|
script: python setup.py test
|
||||||
|
@@ -25,23 +25,19 @@ Detailed description (for [e]pydoc goes here).
|
|||||||
"""
|
"""
|
||||||
from six import reraise
|
from six import reraise
|
||||||
import sys
|
import sys
|
||||||
import threading
|
|
||||||
import thread
|
|
||||||
import types
|
|
||||||
import httplib
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
import itertools
|
|
||||||
import re
|
import re
|
||||||
|
try:
|
||||||
|
from xml.etree import ElementTree
|
||||||
|
except ImportError:
|
||||||
|
from elementtree import ElementTree
|
||||||
|
from xml.parsers.expat import ExpatError
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from requests.auth import HTTPBasicAuth
|
||||||
|
|
||||||
from pyVmomi import vim, vmodl, SoapStubAdapter, SessionOrientedStub
|
from pyVmomi import vim, vmodl, SoapStubAdapter, SessionOrientedStub
|
||||||
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
|
||||||
try:
|
|
||||||
from xml.etree.ElementTree import ElementTree
|
|
||||||
except ImportError:
|
|
||||||
from elementtree.ElementTree import ElementTree
|
|
||||||
from xml.parsers.expat import ExpatError
|
|
||||||
import urllib2
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -57,7 +53,6 @@ Global (thread-shared) ServiceInstance
|
|||||||
@todo: Get rid of me?
|
@todo: Get rid of me?
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class closing(object):
|
class closing(object):
|
||||||
"""
|
"""
|
||||||
Helper class for using closable objects in a 'with' statement,
|
Helper class for using closable objects in a 'with' statement,
|
||||||
@@ -227,7 +222,7 @@ def Connect(host='localhost', port=443, user='root', pwd='',
|
|||||||
host = info.group(1)[1:-1]
|
host = info.group(1)[1:-1]
|
||||||
if info.group(2) is not None:
|
if info.group(2) is not None:
|
||||||
port = int(info.group(2)[1:])
|
port = int(info.group(2)[1:])
|
||||||
except ValueError, ve:
|
except ValueError as ve:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if namespace:
|
if namespace:
|
||||||
@@ -256,7 +251,7 @@ def Disconnect(si):
|
|||||||
def GetLocalTicket(si, user):
|
def GetLocalTicket(si, user):
|
||||||
try:
|
try:
|
||||||
sessionManager = si.content.sessionManager
|
sessionManager = si.content.sessionManager
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if type(e).__name__ == 'ExpatError':
|
if type(e).__name__ == 'ExpatError':
|
||||||
msg = 'Malformed response while querying for local ticket: "%s"' % e
|
msg = 'Malformed response while querying for local ticket: "%s"' % e
|
||||||
raise vim.fault.HostConnectFault(msg=msg)
|
raise vim.fault.HostConnectFault(msg=msg)
|
||||||
@@ -312,14 +307,17 @@ def __Login(host, port, user, pwd, service, adapter, version, path,
|
|||||||
content = si.RetrieveContent()
|
content = si.RetrieveContent()
|
||||||
except vmodl.MethodFault:
|
except vmodl.MethodFault:
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
# NOTE (hartsock): preserve the traceback for diagnostics
|
# NOTE (hartsock): preserve the traceback for diagnostics
|
||||||
# pulling and preserving the traceback makes diagnosing connection
|
# pulling and preserving the traceback makes diagnosing connection
|
||||||
# failures easier since the fault will also include where inside the
|
# failures easier since the fault will also include where inside the
|
||||||
# library the fault occurred. Without the traceback we have no idea
|
# library the fault occurred. Without the traceback we have no idea
|
||||||
# why the connection failed beyond the message string.
|
# why the connection failed beyond the message string.
|
||||||
(type, value, traceback) = sys.exc_info()
|
(type, value, traceback) = sys.exc_info()
|
||||||
|
if traceback:
|
||||||
reraise(vim.fault.HostConnectFault(msg=str(e)), None, traceback)
|
reraise(vim.fault.HostConnectFault(msg=str(e)), None, traceback)
|
||||||
|
else:
|
||||||
|
raise vim.fault.HostConnectFault(msg=str(e))
|
||||||
|
|
||||||
# Get a ticket if we're connecting to localhost and password is not specified
|
# Get a ticket if we're connecting to localhost and password is not specified
|
||||||
if host == 'localhost' and not pwd:
|
if host == 'localhost' and not pwd:
|
||||||
@@ -334,7 +332,7 @@ def __Login(host, port, user, pwd, service, adapter, version, path,
|
|||||||
x = content.sessionManager.Login(user, pwd, None)
|
x = content.sessionManager.Login(user, pwd, None)
|
||||||
except vim.fault.InvalidLogin:
|
except vim.fault.InvalidLogin:
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
raise
|
raise
|
||||||
return si, stub
|
return si, stub
|
||||||
|
|
||||||
@@ -350,7 +348,7 @@ def __Logout(si):
|
|||||||
if si:
|
if si:
|
||||||
content = si.RetrieveContent()
|
content = si.RetrieveContent()
|
||||||
content.sessionManager.Logout()
|
content.sessionManager.Logout()
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@@ -417,7 +415,7 @@ class SmartConnection(object):
|
|||||||
|
|
||||||
def __GetServiceVersionDescription(protocol, server, port, path):
|
def __GetServiceVersionDescription(protocol, server, port, path):
|
||||||
"""
|
"""
|
||||||
Private method that returns an ElementTree describing the API versions
|
Private method that returns a root from an ElementTree describing the API versions
|
||||||
supported by the specified server. The result will be vimServiceVersions.xml
|
supported by the specified server. The result will be vimServiceVersions.xml
|
||||||
if it exists, otherwise vimService.wsdl if it exists, otherwise None.
|
if it exists, otherwise vimService.wsdl if it exists, otherwise None.
|
||||||
|
|
||||||
@@ -431,26 +429,23 @@ def __GetServiceVersionDescription(protocol, server, port, path):
|
|||||||
@type path: string
|
@type path: string
|
||||||
"""
|
"""
|
||||||
|
|
||||||
tree = ElementTree()
|
|
||||||
|
|
||||||
url = "%s://%s:%s/%s/vimServiceVersions.xml" % (protocol, server, port, path)
|
url = "%s://%s:%s/%s/vimServiceVersions.xml" % (protocol, server, port, path)
|
||||||
try:
|
try:
|
||||||
with closing(urllib2.urlopen(url)) as sock:
|
sock = requests.get(url, verify=False)
|
||||||
if sock.getcode() == 200:
|
if sock.status_code == 200:
|
||||||
tree.parse(sock)
|
tree = ElementTree.fromstring(sock.content)
|
||||||
return tree
|
return tree
|
||||||
except ExpatError:
|
except ExpatError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
url = "%s://%s:%s/%s/vimService.wsdl" % (protocol, server, port, path)
|
url = "%s://%s:%s/%s/vimService.wsdl" % (protocol, server, port, path)
|
||||||
try:
|
try:
|
||||||
with closing(urllib2.urlopen(url)) as sock:
|
sock = requests.get(url, verify=False)
|
||||||
if sock.getcode() == 200:
|
if sock.status_code == 200:
|
||||||
tree.parse(sock)
|
tree = ElementTree.fromstring(sock.content)
|
||||||
return tree
|
return tree
|
||||||
except ExpatError:
|
except ExpatError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -465,15 +460,15 @@ def __VersionIsSupported(desiredVersion, serviceVersionDescription):
|
|||||||
@param desiredVersion: The version we want to see if the server supports
|
@param desiredVersion: The version we want to see if the server supports
|
||||||
(eg. vim.version.version2.
|
(eg. vim.version.version2.
|
||||||
@type desiredVersion: string
|
@type desiredVersion: string
|
||||||
@param serviceVersionDescription: An ElementTree for vimServiceVersions.xml
|
@param serviceVersionDescription: A root ElementTree for vimServiceVersions.xml
|
||||||
or vimService.wsdl.
|
or vimService.wsdl.
|
||||||
@type serviceVersionDescription: ElementTree
|
@type serviceVersionDescription: root ElementTree
|
||||||
"""
|
"""
|
||||||
|
|
||||||
root = serviceVersionDescription.getroot()
|
root = serviceVersionDescription
|
||||||
if root.tag == 'namespaces':
|
if root.tag == 'namespaces':
|
||||||
# serviceVersionDescription appears to be a vimServiceVersions.xml document
|
# serviceVersionDescription appears to be a vimServiceVersions.xml document
|
||||||
if root.get('version') <> '1.0':
|
if root.get('version') != '1.0':
|
||||||
raise RuntimeError('vimServiceVersions.xml has version %s,' \
|
raise RuntimeError('vimServiceVersions.xml has version %s,' \
|
||||||
' which is not understood' % (root.get('version')))
|
' which is not understood' % (root.get('version')))
|
||||||
desiredVersionId = versionIdMap[desiredVersion]
|
desiredVersionId = versionIdMap[desiredVersion]
|
||||||
@@ -599,11 +594,7 @@ def OpenUrlWithBasicAuth(url, user='root', pwd=''):
|
|||||||
the specified credentials to the server as part of the request.
|
the specified credentials to the server as part of the request.
|
||||||
Returns the response as a file-like object.
|
Returns the response as a file-like object.
|
||||||
"""
|
"""
|
||||||
pwMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
return requests.get(url, auth=HTTPBasicAuth(user, pwd), verify=False)
|
||||||
pwMgr.add_password(None, url, user, pwd)
|
|
||||||
handler = urllib2.HTTPBasicAuthHandler(pwMgr)
|
|
||||||
opener = urllib2.build_opener(handler)
|
|
||||||
return opener.open(url)
|
|
||||||
|
|
||||||
def OpenPathWithStub(path, stub):
|
def OpenPathWithStub(path, stub):
|
||||||
"""
|
"""
|
||||||
@@ -623,8 +614,8 @@ def OpenPathWithStub(path, stub):
|
|||||||
raise vmodl.fault.NotSupported()
|
raise vmodl.fault.NotSupported()
|
||||||
hostPort = stub.host
|
hostPort = stub.host
|
||||||
url = '%s://%s%s' % (protocol, hostPort, path)
|
url = '%s://%s%s' % (protocol, hostPort, path)
|
||||||
request = urllib2.Request(url)
|
headers = {}
|
||||||
if stub.cookie:
|
if stub.cookie:
|
||||||
request.add_header('Cookie', stub.cookie)
|
headers["Cookie"] = stub.cookie
|
||||||
return urllib2.urlopen(request)
|
return requests.get(url, headers=headers, verify=False)
|
||||||
|
|
||||||
|
@@ -12,9 +12,10 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
# ******* WARNING - AUTO GENERATED CODE - DO NOT EDIT *******
|
# ******* WARNING - AUTO GENERATED CODE - DO NOT EDIT *******
|
||||||
from VmomiSupport import CreateDataType, CreateManagedType, CreateEnumType, AddVersion, AddVersionParent, F_LINK, F_LINKABLE, F_OPTIONAL
|
from pyVmomi.VmomiSupport import CreateDataType, CreateManagedType, CreateEnumType, AddVersion, AddVersionParent, F_LINK, F_LINKABLE, F_OPTIONAL
|
||||||
|
|
||||||
AddVersion("vmodl.query.version.version1", "", "", 0, "vim25")
|
AddVersion("vmodl.query.version.version1", "", "", 0, "vim25")
|
||||||
AddVersion("vmodl.query.version.version2", "", "", 0, "vim25")
|
AddVersion("vmodl.query.version.version2", "", "", 0, "vim25")
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
## Diff any two objects
|
## Diff any two objects
|
||||||
|
from six import text_type
|
||||||
|
from six import u
|
||||||
|
|
||||||
from pyVmomi import VmomiSupport, types
|
from pyVmomi import VmomiSupport, types
|
||||||
import itertools
|
import itertools
|
||||||
@@ -33,7 +35,7 @@ def IsPrimitiveType(obj):
|
|||||||
isinstance(obj, types.short) or isinstance(obj, types.int) or
|
isinstance(obj, types.short) or isinstance(obj, types.int) or
|
||||||
isinstance(obj, types.double) or isinstance(obj, types.float) or
|
isinstance(obj, types.double) or isinstance(obj, types.float) or
|
||||||
isinstance(obj, types.long) or isinstance(obj, types.str) or
|
isinstance(obj, types.long) or isinstance(obj, types.str) or
|
||||||
isinstance(obj, unicode) or
|
isinstance(obj, text_type) or
|
||||||
isinstance(obj, types.PropertyPath) or
|
isinstance(obj, types.PropertyPath) or
|
||||||
isinstance(obj, types.ManagedMethod) or
|
isinstance(obj, types.ManagedMethod) or
|
||||||
isinstance(obj, types.datetime) or
|
isinstance(obj, types.datetime) or
|
||||||
|
@@ -45,7 +45,7 @@ class DynamicTypeImporter:
|
|||||||
if self.hostSystem:
|
if self.hostSystem:
|
||||||
try:
|
try:
|
||||||
dynTypeMgr = self.hostSystem.RetrieveDynamicTypeManager()
|
dynTypeMgr = self.hostSystem.RetrieveDynamicTypeManager()
|
||||||
except vmodl.fault.MethodNotFound, err:
|
except vmodl.fault.MethodNotFound as err:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if not dynTypeMgr:
|
if not dynTypeMgr:
|
||||||
@@ -139,7 +139,7 @@ class DynamicTypeConstructor:
|
|||||||
for typeInfo in infos:
|
for typeInfo in infos:
|
||||||
try:
|
try:
|
||||||
fn(*typeInfo)
|
fn(*typeInfo)
|
||||||
except Exception, err:
|
except Exception as err:
|
||||||
#Ignore errors due to duplicate importing
|
#Ignore errors due to duplicate importing
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@@ -14,12 +14,14 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import print_function
|
||||||
|
# TODO (hartsocks): Introduce logging to remove the need for print function.
|
||||||
"""
|
"""
|
||||||
This module is for ISO 8601 parsing
|
This module is for ISO 8601 parsing
|
||||||
"""
|
"""
|
||||||
__author__ = 'VMware, Inc.'
|
__author__ = 'VMware, Inc.'
|
||||||
|
|
||||||
|
from six import iteritems
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timedelta, tzinfo
|
from datetime import datetime, timedelta, tzinfo
|
||||||
import re
|
import re
|
||||||
@@ -118,7 +120,7 @@ def ParseISO8601(datetimeStr):
|
|||||||
if match:
|
if match:
|
||||||
try:
|
try:
|
||||||
dt = {}
|
dt = {}
|
||||||
for key, defaultVal in _dtExprKeyDefValMap.iteritems():
|
for key, defaultVal in iteritems(_dtExprKeyDefValMap):
|
||||||
val = match.group(key)
|
val = match.group(key)
|
||||||
if val:
|
if val:
|
||||||
if key == 'microsecond':
|
if key == 'microsecond':
|
||||||
@@ -176,7 +178,7 @@ def ParseISO8601(datetimeStr):
|
|||||||
datetimeVal = datetime(**dt)
|
datetimeVal = datetime(**dt)
|
||||||
if delta:
|
if delta:
|
||||||
datetimeVal += delta
|
datetimeVal += delta
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
return datetimeVal
|
return datetimeVal
|
||||||
|
|
||||||
@@ -253,7 +255,7 @@ if __name__ == '__main__':
|
|||||||
]:
|
]:
|
||||||
dt = ParseISO8601(testStr)
|
dt = ParseISO8601(testStr)
|
||||||
if dt == None:
|
if dt == None:
|
||||||
print 'Failed to parse (%s)' % testStr
|
print('Failed to parse ({0})'.format(testStr))
|
||||||
assert(False)
|
assert(False)
|
||||||
|
|
||||||
# Make sure we can translate back
|
# Make sure we can translate back
|
||||||
@@ -262,16 +264,16 @@ if __name__ == '__main__':
|
|||||||
if dt.tzinfo is None:
|
if dt.tzinfo is None:
|
||||||
dt = dt.replace(tzinfo=dt1.tzinfo)
|
dt = dt.replace(tzinfo=dt1.tzinfo)
|
||||||
if dt1 != dt:
|
if dt1 != dt:
|
||||||
print 'ParseISO8601 -> ISO8601Format -> ParseISO8601 failed (%s)' % testStr
|
print('ParseISO8601 -> ISO8601Format -> ParseISO8601 failed ({0})'.format(testStr))
|
||||||
assert(False)
|
assert(False)
|
||||||
|
|
||||||
# Make sure we can parse python isoformat()
|
# Make sure we can parse python isoformat()
|
||||||
dt2 = ParseISO8601(dt.isoformat())
|
dt2 = ParseISO8601(dt.isoformat())
|
||||||
if dt2 == None:
|
if dt2 == None:
|
||||||
print 'ParseISO8601("%s".isoformat()) failed' % testStr
|
print('ParseISO8601("{0}".isoformat()) failed'.format(testStr))
|
||||||
assert(False)
|
assert(False)
|
||||||
|
|
||||||
print testStr, '->', dt, isoformat
|
print(testStr, '->', dt, isoformat)
|
||||||
|
|
||||||
# Basic form
|
# Basic form
|
||||||
for testStr in [
|
for testStr in [
|
||||||
@@ -293,7 +295,7 @@ if __name__ == '__main__':
|
|||||||
# Reject for now
|
# Reject for now
|
||||||
dt = ParseISO8601(testStr)
|
dt = ParseISO8601(testStr)
|
||||||
if dt != None:
|
if dt != None:
|
||||||
print 'ParseISO8601 (%s) should fail, but it did not' % testStr
|
print('ParseISO8601 ({0}) should fail, but it did not'.format(testStr))
|
||||||
assert(False)
|
assert(False)
|
||||||
#print testStr, '->', dt
|
#print testStr, '->', dt
|
||||||
#assert(dt != None)
|
#assert(dt != None)
|
||||||
@@ -352,5 +354,5 @@ if __name__ == '__main__':
|
|||||||
]:
|
]:
|
||||||
dt = ParseISO8601(testStr)
|
dt = ParseISO8601(testStr)
|
||||||
if dt != None:
|
if dt != None:
|
||||||
print 'ParseISO8601 (%s) should fail, but it did not' % testStr
|
print('ParseISO8601 ({0}) should fail, but it did not'.format(testStr))
|
||||||
assert(False)
|
assert(False)
|
||||||
|
@@ -12,9 +12,10 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
# ******* WARNING - AUTO GENERATED CODE - DO NOT EDIT *******
|
# ******* WARNING - AUTO GENERATED CODE - DO NOT EDIT *******
|
||||||
from VmomiSupport import CreateDataType, CreateManagedType, CreateEnumType, AddVersion, AddVersionParent, F_LINK, F_LINKABLE, F_OPTIONAL
|
from pyVmomi.VmomiSupport import CreateDataType, CreateManagedType, CreateEnumType, AddVersion, AddVersionParent, F_LINK, F_LINKABLE, F_OPTIONAL
|
||||||
|
|
||||||
AddVersion("vim.version.version1", "vim2", "2.0", 1, "vim25")
|
AddVersion("vim.version.version1", "vim2", "2.0", 1, "vim25")
|
||||||
AddVersion("vim.version.version2", "vim25", "2.5", 0, "vim25")
|
AddVersion("vim.version.version2", "vim25", "2.5", 0, "vim25")
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
# VMware vSphere Python SDK
|
# VMware vSphere Python SDK
|
||||||
# Copyright (c) 2008-2014 VMware, Inc. All Rights Reserved.
|
# Copyright (c) 2008-2013 VMware, Inc. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -12,23 +12,35 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from six import PY2
|
||||||
|
from six import PY3
|
||||||
|
|
||||||
from six.moves import http_client
|
from six.moves import http_client
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
long = int
|
||||||
|
basestring = str
|
||||||
|
from six import u
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import time
|
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import thread
|
import time
|
||||||
import urlparse
|
from six.moves.urllib.parse import urlparse
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from xml.parsers.expat import ParserCreate
|
from xml.parsers.expat import ParserCreate
|
||||||
# We have our own escape functionality.
|
# We have our own escape functionality.
|
||||||
# from xml.sax.saxutils import escape
|
# from xml.sax.saxutils import escape
|
||||||
|
if PY2:
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
from VmomiSupport import *
|
|
||||||
from StubAdapterAccessorImpl import StubAdapterAccessorMixin
|
if PY3:
|
||||||
import Iso8601
|
from io import StringIO
|
||||||
|
from pyVmomi.VmomiSupport import *
|
||||||
|
from pyVmomi.StubAdapterAccessorImpl import StubAdapterAccessorMixin
|
||||||
|
import pyVmomi.Iso8601
|
||||||
import base64
|
import base64
|
||||||
from xml.parsers.expat import ExpatError
|
from xml.parsers.expat import ExpatError
|
||||||
import copy
|
import copy
|
||||||
@@ -46,41 +58,41 @@ CONNECTION_POOL_IDLE_TIMEOUT_SEC = 900
|
|||||||
NS_SEP = " "
|
NS_SEP = " "
|
||||||
|
|
||||||
XML_ENCODING = 'UTF-8'
|
XML_ENCODING = 'UTF-8'
|
||||||
XML_HEADER = '<?xml version="1.0" encoding="%s"?>' % XML_ENCODING
|
XML_HEADER = '<?xml version="1.0" encoding="{0}"?>'.format(XML_ENCODING)
|
||||||
|
|
||||||
XMLNS_SOAPENC = "http://schemas.xmlsoap.org/soap/encoding/"
|
XMLNS_SOAPENC = "http://schemas.xmlsoap.org/soap/encoding/"
|
||||||
XMLNS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/"
|
XMLNS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
|
||||||
XSI_TYPE = XMLNS_XSI + NS_SEP + u'type'
|
XSI_TYPE = XMLNS_XSI + NS_SEP + u('type')
|
||||||
|
|
||||||
# Note: Must make a copy to use the SOAP_NSMAP
|
# Note: Must make a copy to use the SOAP_NSMAP
|
||||||
# TODO: Change to frozendict, if available
|
# TODO: Change to frozendict, if available
|
||||||
SOAP_NSMAP = { XMLNS_SOAPENC: 'soapenc', XMLNS_SOAPENV: 'soapenv',
|
SOAP_NSMAP = { XMLNS_SOAPENC: 'soapenc', XMLNS_SOAPENV: 'soapenv',
|
||||||
XMLNS_XSI: 'xsi', XMLNS_XSD: 'xsd' }
|
XMLNS_XSI: 'xsi', XMLNS_XSD: 'xsd' }
|
||||||
|
|
||||||
SOAP_ENVELOPE_TAG="%s:Envelope" % SOAP_NSMAP[XMLNS_SOAPENV]
|
SOAP_ENVELOPE_TAG = "{0}:Envelope".format(SOAP_NSMAP[XMLNS_SOAPENV])
|
||||||
SOAP_HEADER_TAG="%s:Header" % SOAP_NSMAP[XMLNS_SOAPENV]
|
SOAP_HEADER_TAG = "{0}:Header".format(SOAP_NSMAP[XMLNS_SOAPENV])
|
||||||
SOAP_FAULT_TAG="%s:Fault" % SOAP_NSMAP[XMLNS_SOAPENV]
|
SOAP_FAULT_TAG = "{0}:Fault".format(SOAP_NSMAP[XMLNS_SOAPENV])
|
||||||
SOAP_BODY_TAG="%s:Body" % SOAP_NSMAP[XMLNS_SOAPENV]
|
SOAP_BODY_TAG = "{0}:Body".format(SOAP_NSMAP[XMLNS_SOAPENV])
|
||||||
|
|
||||||
SOAP_ENVELOPE_START = '<%s ' % SOAP_ENVELOPE_TAG + \
|
SOAP_ENVELOPE_START = '<{0} '.format(SOAP_ENVELOPE_TAG) + \
|
||||||
' '.join(['xmlns:' + prefix + '="' + urn + '"' \
|
' '.join(['xmlns:' + prefix + '="' + urn + '"' \
|
||||||
for urn, prefix in SOAP_NSMAP.iteritems()]) + \
|
for urn, prefix in iteritems(SOAP_NSMAP)]) + \
|
||||||
'>\n'
|
'>\n'
|
||||||
SOAP_ENVELOPE_END = "\n</%s>" % (SOAP_ENVELOPE_TAG)
|
SOAP_ENVELOPE_END = "\n</{0}>".format(SOAP_ENVELOPE_TAG)
|
||||||
SOAP_HEADER_START="<%s>" % SOAP_HEADER_TAG
|
SOAP_HEADER_START = "<{0}>".format(SOAP_HEADER_TAG)
|
||||||
SOAP_HEADER_END="</%s>" % SOAP_HEADER_TAG
|
SOAP_HEADER_END = "</{0}>".format(SOAP_HEADER_TAG)
|
||||||
SOAP_BODY_START="<%s>" % SOAP_BODY_TAG
|
SOAP_BODY_START = "<{0}>".format(SOAP_BODY_TAG)
|
||||||
SOAP_BODY_END="</%s>" % SOAP_BODY_TAG
|
SOAP_BODY_END = "</{0}>".format(SOAP_BODY_TAG)
|
||||||
SOAP_START = SOAP_ENVELOPE_START + SOAP_BODY_START + '\n'
|
SOAP_START = SOAP_ENVELOPE_START + SOAP_BODY_START + '\n'
|
||||||
SOAP_END = '\n' + SOAP_BODY_END + SOAP_ENVELOPE_END
|
SOAP_END = '\n' + SOAP_BODY_END + SOAP_ENVELOPE_END
|
||||||
|
|
||||||
WSSE_PREFIX = "wsse"
|
WSSE_PREFIX = "wsse"
|
||||||
WSSE_HEADER_TAG="%s:Security" % WSSE_PREFIX
|
WSSE_HEADER_TAG = "{0}:Security".format(WSSE_PREFIX)
|
||||||
WSSE_NS_URL = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
WSSE_NS_URL = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
||||||
WSSE_NS='xmlns:%s="%s"' % (WSSE_PREFIX, WSSE_NS_URL)
|
WSSE_NS = 'xmlns:{0}="{1}"'.format(WSSE_PREFIX, WSSE_NS_URL)
|
||||||
WSSE_HEADER_START="<%s %s>" % (WSSE_HEADER_TAG, WSSE_NS)
|
WSSE_HEADER_START = "<{0} {1}>".format(WSSE_HEADER_TAG, WSSE_NS)
|
||||||
WSSE_HEADER_END="</%s>" % WSSE_HEADER_TAG
|
WSSE_HEADER_END = "</{0}>".format(WSSE_HEADER_TAG)
|
||||||
|
|
||||||
## MethodFault type
|
## MethodFault type
|
||||||
MethodFault = GetVmodlType("vmodl.MethodFault")
|
MethodFault = GetVmodlType("vmodl.MethodFault")
|
||||||
@@ -152,7 +164,7 @@ def SerializeFaultDetail(val, info=None, version=None, nsMap=None, encoding=None
|
|||||||
if version is None:
|
if version is None:
|
||||||
try:
|
try:
|
||||||
if not isinstance(val, MethodFault):
|
if not isinstance(val, MethodFault):
|
||||||
raise TypeError('%s is not a MethodFault' % str(val))
|
raise TypeError('{0} is not a MethodFault'.format(str(val)))
|
||||||
version = val._version
|
version = val._version
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
version = BASE_VERSION
|
version = BASE_VERSION
|
||||||
@@ -178,7 +190,7 @@ class SoapSerializer:
|
|||||||
self.version = version
|
self.version = version
|
||||||
self.nsMap = nsMap and nsMap or {}
|
self.nsMap = nsMap and nsMap or {}
|
||||||
self.encoding = encoding and encoding or XML_ENCODING
|
self.encoding = encoding and encoding or XML_ENCODING
|
||||||
for ns, prefix in self.nsMap.iteritems():
|
for ns, prefix in iteritems(self.nsMap):
|
||||||
if prefix == '':
|
if prefix == '':
|
||||||
self.defaultNS = ns
|
self.defaultNS = ns
|
||||||
break
|
break
|
||||||
@@ -194,7 +206,7 @@ class SoapSerializer:
|
|||||||
prefix = self.nsMap.get(ns)
|
prefix = self.nsMap.get(ns)
|
||||||
if not prefix:
|
if not prefix:
|
||||||
prefix = nsPrefix
|
prefix = nsPrefix
|
||||||
self.outermostAttrs += ' xmlns:%s="%s"' % (prefix, ns)
|
self.outermostAttrs += ' xmlns:{0}="{1}"'.format(prefix, ns)
|
||||||
self.nsMap = self.nsMap.copy()
|
self.nsMap = self.nsMap.copy()
|
||||||
self.nsMap[ns] = prefix
|
self.nsMap[ns] = prefix
|
||||||
setattr(self, attrName, prefix + ":")
|
setattr(self, attrName, prefix + ":")
|
||||||
@@ -240,7 +252,7 @@ class SoapSerializer:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
# We have not seen this ns before
|
# We have not seen this ns before
|
||||||
prefix = ns.split(':', 1)[-1]
|
prefix = ns.split(':', 1)[-1]
|
||||||
attr = ' xmlns:%s="%s"' % (prefix, ns)
|
attr = ' xmlns:{0}="{1}"'.format(prefix, ns)
|
||||||
return attr, prefix and prefix + ':' + name or name
|
return attr, prefix and prefix + ':' + name or name
|
||||||
|
|
||||||
## Serialize an object (internal)
|
## Serialize an object (internal)
|
||||||
@@ -257,17 +269,17 @@ class SoapSerializer:
|
|||||||
if info.flags & F_OPTIONAL:
|
if info.flags & F_OPTIONAL:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise TypeError('Field "%s" is not optional' % info.name)
|
raise TypeError('Field "{0}" is not optional'.format(info.name))
|
||||||
elif isinstance(val, list) and len(val) == 0:
|
elif isinstance(val, list) and len(val) == 0:
|
||||||
if info.type is object:
|
if info.type is object:
|
||||||
# Make sure an empty array assigned to Any is typed
|
# Make sure an empty array assigned to Any is typed
|
||||||
if not isinstance(val, Array):
|
if not isinstance(val, Array):
|
||||||
raise TypeError('Field "%s": Cannot assign empty native python array to an Any' % info.name)
|
raise TypeError('Field "{0}": Cannot assign empty native python array to an Any'.format(info.name))
|
||||||
elif info.flags & F_OPTIONAL:
|
elif info.flags & F_OPTIONAL:
|
||||||
# Skip optional non-Any
|
# Skip optional non-Any
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
raise TypeError('Field "%s" is not optional' % info.name)
|
raise TypeError('Field "{0}" not optional'.format(info.name))
|
||||||
|
|
||||||
if self.outermostAttrs:
|
if self.outermostAttrs:
|
||||||
attr = self.outermostAttrs
|
attr = self.outermostAttrs
|
||||||
@@ -278,7 +290,7 @@ class SoapSerializer:
|
|||||||
# Emit default ns if tag ns is not the same
|
# Emit default ns if tag ns is not the same
|
||||||
currTagNS = GetWsdlNamespace(info.version)
|
currTagNS = GetWsdlNamespace(info.version)
|
||||||
if currTagNS != defNS:
|
if currTagNS != defNS:
|
||||||
attr += ' xmlns="%s"' % currTagNS
|
attr += ' xmlns="{0}"'.format(currTagNS)
|
||||||
currDefNS = currTagNS
|
currDefNS = currTagNS
|
||||||
|
|
||||||
if isinstance(val, DataObject):
|
if isinstance(val, DataObject):
|
||||||
@@ -296,14 +308,14 @@ class SoapSerializer:
|
|||||||
elif isinstance(val, ManagedObject):
|
elif isinstance(val, ManagedObject):
|
||||||
if info.type is object:
|
if info.type is object:
|
||||||
nsattr, qName = self._QName(ManagedObject, currDefNS)
|
nsattr, qName = self._QName(ManagedObject, currDefNS)
|
||||||
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
|
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
|
||||||
if val._serverGuid is not None:
|
if val._serverGuid is not None:
|
||||||
attr += ' serverGuid="%s"' % (val._serverGuid)
|
attr += ' serverGuid="{0}"'.format(val._serverGuid)
|
||||||
# val in vim type attr is not namespace qualified
|
# val in vim type attr is not namespace qualified
|
||||||
# TODO: Add a new "typens" attr?
|
# TODO: Add a new "typens" attr?
|
||||||
ns, name = GetQualifiedWsdlName(Type(val))
|
ns, name = GetQualifiedWsdlName(Type(val))
|
||||||
attr += ' type="%s"' % (name)
|
attr += ' type="{0}"'.format(name)
|
||||||
self.writer.write('<%s%s>%s</%s>' % (info.name, attr,
|
self.writer.write('<{0}{1}>{2}</{3}>'.format(info.name, attr,
|
||||||
val._moId.encode(self.encoding),
|
val._moId.encode(self.encoding),
|
||||||
info.name))
|
info.name))
|
||||||
elif isinstance(val, list):
|
elif isinstance(val, list):
|
||||||
@@ -326,14 +338,14 @@ class SoapSerializer:
|
|||||||
if qName.endswith("ArrayOfManagedObject"):
|
if qName.endswith("ArrayOfManagedObject"):
|
||||||
qName += "Reference"
|
qName += "Reference"
|
||||||
|
|
||||||
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
|
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
|
||||||
self.writer.write('<%s%s>' % (info.name, attr))
|
self.writer.write('<{0}{1}>'.format(info.name, attr))
|
||||||
|
|
||||||
itemInfo = Object(name=tag, type=itemType,
|
itemInfo = Object(name=tag, type=itemType,
|
||||||
version=info.version, flags=info.flags)
|
version=info.version, flags=info.flags)
|
||||||
for it in val:
|
for it in val:
|
||||||
self._Serialize(it, itemInfo, currDefNS)
|
self._Serialize(it, itemInfo, currDefNS)
|
||||||
self.writer.write('</%s>' % info.name)
|
self.writer.write('</{0}>'.format(info.name))
|
||||||
else:
|
else:
|
||||||
itemType = info.type.Item
|
itemType = info.type.Item
|
||||||
itemInfo = Object(name=info.name, type=itemType,
|
itemInfo = Object(name=info.name, type=itemType,
|
||||||
@@ -342,54 +354,52 @@ class SoapSerializer:
|
|||||||
self._Serialize(it, itemInfo, defNS)
|
self._Serialize(it, itemInfo, defNS)
|
||||||
elif isinstance(val, type) or isinstance(val, type(Exception)):
|
elif isinstance(val, type) or isinstance(val, type(Exception)):
|
||||||
if info.type is object:
|
if info.type is object:
|
||||||
attr += ' %stype="%sstring"' % (self.xsiPrefix, self.xsdPrefix)
|
attr += ' {0}type="{1}string"'.format(self.xsiPrefix, self.xsdPrefix)
|
||||||
self.writer.write('<%s%s>%s</%s>' %
|
self.writer.write('<{0}{1}>{2}</{0}>'.format(
|
||||||
(info.name, attr, GetWsdlName(val), info.name))
|
info.name, attr, GetWsdlName(val)))
|
||||||
elif isinstance(val, ManagedMethod):
|
elif isinstance(val, ManagedMethod):
|
||||||
if info.type is object:
|
if info.type is object:
|
||||||
attr += ' %stype="%sstring"' % (self.xsiPrefix, self.xsdPrefix)
|
attr += ' {0}type="{1}string"'.format(self.xsiPrefix, self.xsdPrefix)
|
||||||
self.writer.write('<%s%s>%s</%s>' %
|
self.writer.write('<{0}{1}>{2}</{0}>'.format(
|
||||||
(info.name, attr, val.info.wsdlName, info.name))
|
info.name, attr, val.info.wsdlName))
|
||||||
elif isinstance(val, datetime):
|
elif isinstance(val, datetime):
|
||||||
if info.type is object:
|
if info.type is object:
|
||||||
nsattr, qName = self._QName(Type(val), currDefNS)
|
nsattr, qName = self._QName(Type(val), currDefNS)
|
||||||
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
|
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
|
||||||
result = Iso8601.ISO8601Format(val)
|
result = Iso8601.ISO8601Format(val)
|
||||||
self.writer.write('<%s%s>%s</%s>' % (info.name, attr, result,
|
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr, result))
|
||||||
info.name))
|
|
||||||
elif isinstance(val, binary):
|
elif isinstance(val, binary):
|
||||||
if info.type is object:
|
if info.type is object:
|
||||||
nsattr, qName = self._QName(Type(val), currDefNS)
|
nsattr, qName = self._QName(Type(val), currDefNS)
|
||||||
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
|
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
|
||||||
result = base64.b64encode(val)
|
result = base64.b64encode(val)
|
||||||
self.writer.write('<%s%s>%s</%s>' % (info.name, attr, result,
|
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr, result))
|
||||||
info.name))
|
|
||||||
elif isinstance(val, bool):
|
elif isinstance(val, bool):
|
||||||
if info.type is object:
|
if info.type is object:
|
||||||
nsattr, qName = self._QName(Type(val), currDefNS)
|
nsattr, qName = self._QName(Type(val), currDefNS)
|
||||||
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
|
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
|
||||||
result = val and "true" or "false"
|
result = val and "true" or "false"
|
||||||
self.writer.write('<%s%s>%s</%s>' % (info.name, attr, result,
|
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr, result))
|
||||||
info.name))
|
|
||||||
else:
|
else:
|
||||||
if info.type is object:
|
if info.type is object:
|
||||||
if isinstance(val, PropertyPath):
|
if isinstance(val, PropertyPath):
|
||||||
attr += ' %stype="%sstring"' % (self.xsiPrefix, self.xsdPrefix)
|
attr += ' {0}type="{1}string"'.format(self.xsiPrefix, self.xsdPrefix)
|
||||||
else:
|
else:
|
||||||
nsattr, qName = self._QName(Type(val), currDefNS)
|
nsattr, qName = self._QName(Type(val), currDefNS)
|
||||||
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
|
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
|
||||||
if not isinstance(val, unicode):
|
if not isinstance(val, text_type):
|
||||||
# Use UTF-8 rather than self.encoding. self.encoding is for
|
# Use UTF-8 rather than self.encoding. self.encoding is for
|
||||||
# output of serializer, while 'val' is our input. And regardless
|
# output of serializer, while 'val' is our input. And regardless
|
||||||
# of what our output is, our input should be always UTF-8. Yes,
|
# of what our output is, our input should be always UTF-8. Yes,
|
||||||
# it means that if you emit output in other encoding than UTF-8,
|
# it means that if you emit output in other encoding than UTF-8,
|
||||||
# you cannot serialize it again once more. That's feature, not
|
# you cannot serialize it again once more. That's feature, not
|
||||||
# a bug.
|
# a bug.
|
||||||
val = str(val).decode('UTF-8')
|
val = str(val)
|
||||||
|
if PY2:
|
||||||
|
val = val.decode('UTF-8')
|
||||||
result = XmlEscape(val)
|
result = XmlEscape(val)
|
||||||
self.writer.write('<%s%s>%s</%s>' % (info.name, attr,
|
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr,
|
||||||
result.encode(self.encoding),
|
result.encode(self.encoding)))
|
||||||
info.name))
|
|
||||||
|
|
||||||
## Serialize a a data object (internal)
|
## Serialize a a data object (internal)
|
||||||
#
|
#
|
||||||
@@ -406,8 +416,8 @@ class SoapSerializer:
|
|||||||
dynType = GetCompatibleType(Type(val), self.version)
|
dynType = GetCompatibleType(Type(val), self.version)
|
||||||
if dynType != info.type:
|
if dynType != info.type:
|
||||||
nsattr, qName = self._QName(dynType, currDefNS)
|
nsattr, qName = self._QName(dynType, currDefNS)
|
||||||
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
|
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
|
||||||
self.writer.write('<%s%s>' % (info.name, attr))
|
self.writer.write('<{0}{1}>'.format(info.name, attr))
|
||||||
if dynType is LocalizedMethodFault:
|
if dynType is LocalizedMethodFault:
|
||||||
# Serialize a MethodFault as LocalizedMethodFault on wire
|
# Serialize a MethodFault as LocalizedMethodFault on wire
|
||||||
# See PR 670229
|
# See PR 670229
|
||||||
@@ -423,7 +433,7 @@ class SoapSerializer:
|
|||||||
for prop in val._GetPropertyList():
|
for prop in val._GetPropertyList():
|
||||||
self._Serialize(getattr(val, prop.name), prop, currDefNS)
|
self._Serialize(getattr(val, prop.name), prop, currDefNS)
|
||||||
|
|
||||||
self.writer.write('</%s>' % info.name)
|
self.writer.write('</{0}>'.format(info.name))
|
||||||
|
|
||||||
|
|
||||||
## Deserialize an object from a file or string
|
## Deserialize an object from a file or string
|
||||||
@@ -582,7 +592,7 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
|
|||||||
if name == "fault" and isinstance(self.stack[-1], LocalizedMethodFault):
|
if name == "fault" and isinstance(self.stack[-1], LocalizedMethodFault):
|
||||||
deserializeAsLocalizedMethodFault = False
|
deserializeAsLocalizedMethodFault = False
|
||||||
else:
|
else:
|
||||||
raise TypeError("Invalid type for tag %s" % tag)
|
raise TypeError("Invalid type for tag {0}".format(tag))
|
||||||
|
|
||||||
xsiType = attr.get(XSI_TYPE)
|
xsiType = attr.get(XSI_TYPE)
|
||||||
if xsiType:
|
if xsiType:
|
||||||
@@ -604,13 +614,13 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
|
|||||||
if self.version:
|
if self.version:
|
||||||
objType = GetCompatibleType(objType, self.version)
|
objType = GetCompatibleType(objType, self.version)
|
||||||
if issubclass(objType, ManagedObject):
|
if issubclass(objType, ManagedObject):
|
||||||
typeAttr = attr[u'type']
|
typeAttr = attr[u('type')]
|
||||||
# val in vim type attr is not namespace qualified
|
# val in vim type attr is not namespace qualified
|
||||||
# However, this doesn't hurt to strip out namespace
|
# However, this doesn't hurt to strip out namespace
|
||||||
# TODO: Get the ns from "typens" attr?
|
# TODO: Get the ns from "typens" attr?
|
||||||
ns, name = self.GetNSAndWsdlname(typeAttr)
|
ns, name = self.GetNSAndWsdlname(typeAttr)
|
||||||
if u'serverGuid' in attr:
|
if u('serverGuid') in attr:
|
||||||
self.serverGuid = attr[u'serverGuid']
|
self.serverGuid = attr[u('serverGuid')]
|
||||||
self.stack.append(GuessWsdlType(name))
|
self.stack.append(GuessWsdlType(name))
|
||||||
elif issubclass(objType, DataObject) or issubclass(objType, list):
|
elif issubclass(objType, DataObject) or issubclass(objType, list):
|
||||||
if deserializeAsLocalizedMethodFault and issubclass(objType, Exception):
|
if deserializeAsLocalizedMethodFault and issubclass(objType, Exception):
|
||||||
@@ -662,10 +672,10 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
|
|||||||
elif obj is str:
|
elif obj is str:
|
||||||
try:
|
try:
|
||||||
obj = str(data)
|
obj = str(data)
|
||||||
except UnicodeError:
|
except ValueError:
|
||||||
obj = data
|
obj = data
|
||||||
elif obj is datetime:
|
elif obj is datetime:
|
||||||
obj = Iso8601.ParseISO8601(data)
|
obj = pyVmomi.Iso8601.ParseISO8601(data)
|
||||||
if not obj:
|
if not obj:
|
||||||
raise TypeError(data)
|
raise TypeError(data)
|
||||||
# issubclass is very expensive. Test last
|
# issubclass is very expensive. Test last
|
||||||
@@ -772,7 +782,7 @@ class SoapResponseDeserializer(ExpatDeserializerNSHandlers):
|
|||||||
if self.isFault and tag == "faultstring":
|
if self.isFault and tag == "faultstring":
|
||||||
try:
|
try:
|
||||||
self.msg = str(self.data)
|
self.msg = str(self.data)
|
||||||
except UnicodeError:
|
except ValueError:
|
||||||
self.msg = self.data
|
self.msg = self.data
|
||||||
|
|
||||||
## Base class that implements common functionality for stub adapters.
|
## Base class that implements common functionality for stub adapters.
|
||||||
@@ -789,7 +799,7 @@ class StubAdapterBase(StubAdapterAccessorMixin):
|
|||||||
def ComputeVersionInfo(self, version):
|
def ComputeVersionInfo(self, version):
|
||||||
versionNS = GetVersionNamespace(version)
|
versionNS = GetVersionNamespace(version)
|
||||||
if versionNS.find("/") >= 0:
|
if versionNS.find("/") >= 0:
|
||||||
self.versionId = '"urn:%s"' % versionNS
|
self.versionId = '"urn:{0}"'.format(versionNS)
|
||||||
else:
|
else:
|
||||||
self.versionId = ''
|
self.versionId = ''
|
||||||
self.version = version
|
self.version = version
|
||||||
@@ -822,17 +832,17 @@ class SoapStubAdapterBase(StubAdapterBase):
|
|||||||
|
|
||||||
if reqContexts or samlToken:
|
if reqContexts or samlToken:
|
||||||
result.append(SOAP_HEADER_START)
|
result.append(SOAP_HEADER_START)
|
||||||
for key, val in reqContexts.iteritems():
|
for key, val in iteritems(reqContexts):
|
||||||
# Note: Support req context of string type only
|
# Note: Support req context of string type only
|
||||||
if not isinstance(val, basestring):
|
if not isinstance(val, basestring):
|
||||||
raise TypeError("Request context key (%s) has non-string value (%s) of %s" % (key, val, type(val)))
|
raise TypeError("Request context key ({0}) has non-string value ({1}) of {2}".format(key, val, type(val)))
|
||||||
ret = Serialize(val,
|
ret = Serialize(val,
|
||||||
Object(name=key, type=str, version=self.version),
|
Object(name=key, type=str, version=self.version),
|
||||||
self.version,
|
self.version,
|
||||||
nsMap)
|
nsMap)
|
||||||
result.append(ret)
|
result.append(ret)
|
||||||
if samlToken:
|
if samlToken:
|
||||||
result.append('%s %s %s' % (WSSE_HEADER_START,
|
result.append('{0} {1} {2}'.format(WSSE_HEADER_START,
|
||||||
samlToken,
|
samlToken,
|
||||||
WSSE_HEADER_END))
|
WSSE_HEADER_END))
|
||||||
result.append(SOAP_HEADER_END)
|
result.append(SOAP_HEADER_END)
|
||||||
@@ -840,7 +850,7 @@ class SoapStubAdapterBase(StubAdapterBase):
|
|||||||
|
|
||||||
# Serialize soap body
|
# Serialize soap body
|
||||||
result.extend([SOAP_BODY_START,
|
result.extend([SOAP_BODY_START,
|
||||||
'<%s xmlns="%s">' % (info.wsdlName, defaultNS),
|
'<{0} xmlns="{1}">'.format(info.wsdlName, defaultNS),
|
||||||
Serialize(mo, Object(name="_this", type=ManagedObject,
|
Serialize(mo, Object(name="_this", type=ManagedObject,
|
||||||
version=self.version),
|
version=self.version),
|
||||||
self.version, nsMap)])
|
self.version, nsMap)])
|
||||||
@@ -848,7 +858,7 @@ class SoapStubAdapterBase(StubAdapterBase):
|
|||||||
# Serialize soap request parameters
|
# Serialize soap request parameters
|
||||||
for (param, arg) in zip(info.params, args):
|
for (param, arg) in zip(info.params, args):
|
||||||
result.append(Serialize(arg, param, self.version, nsMap))
|
result.append(Serialize(arg, param, self.version, nsMap))
|
||||||
result.extend(['</%s>' % info.wsdlName, SOAP_BODY_END, SOAP_ENVELOPE_END])
|
result.extend(['</{0}>'.format(info.wsdlName), SOAP_BODY_END, SOAP_ENVELOPE_END])
|
||||||
return ''.join(result)
|
return ''.join(result)
|
||||||
|
|
||||||
## Subclass of HTTPConnection that connects over a Unix domain socket
|
## Subclass of HTTPConnection that connects over a Unix domain socket
|
||||||
@@ -894,8 +904,8 @@ 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: %s "
|
raise Exception("Server has wrong SHA1 thumbprint: {0} "
|
||||||
"(required) != %s (server)" % (
|
"(required) != {1} (server)".format(
|
||||||
thumbprint, sha1Digest))
|
thumbprint, sha1Digest))
|
||||||
|
|
||||||
# Function used to wrap sockets with SSL
|
# Function used to wrap sockets with SSL
|
||||||
@@ -1001,7 +1011,7 @@ class SSLTunnelConnection(object):
|
|||||||
resp = tunnel.getresponse()
|
resp = tunnel.getresponse()
|
||||||
tunnelSocket = resp.fp
|
tunnelSocket = resp.fp
|
||||||
if resp.status != 200:
|
if resp.status != 200:
|
||||||
raise http_client.HTTPException("%d %s" % (resp.status, resp.reason))
|
raise httplib.HTTPException("{0} {1}".format(resp.status, resp.reason))
|
||||||
retval = http_client.HTTPSConnection(path)
|
retval = http_client.HTTPSConnection(path)
|
||||||
retval.sock = _SocketWrapper(tunnelSocket,
|
retval.sock = _SocketWrapper(tunnelSocket,
|
||||||
keyfile=key_file, certfile=cert_file)
|
keyfile=key_file, certfile=cert_file)
|
||||||
@@ -1139,13 +1149,13 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
or (port, HTTPSConnectionWrapper)
|
or (port, HTTPSConnectionWrapper)
|
||||||
if host.find(':') != -1: # is IPv6?
|
if host.find(':') != -1: # is IPv6?
|
||||||
host = '[' + host + ']'
|
host = '[' + host + ']'
|
||||||
self.host = '%s:%d' % (host, port)
|
self.host = '{0}:{1}'.format(host, port)
|
||||||
|
|
||||||
self.path = path
|
self.path = path
|
||||||
if thumbprint:
|
if thumbprint:
|
||||||
self.thumbprint = thumbprint.replace(":", "").lower()
|
self.thumbprint = thumbprint.replace(":", "").lower()
|
||||||
if len(self.thumbprint) != 40:
|
if len(self.thumbprint) != 40:
|
||||||
raise Exception("Invalid SHA1 thumbprint -- %s" % thumbprint)
|
raise Exception("Invalid SHA1 thumbprint -- {0}".format(thumbprint))
|
||||||
else:
|
else:
|
||||||
self.thumbprint = None
|
self.thumbprint = None
|
||||||
|
|
||||||
@@ -1158,13 +1168,13 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
if url:
|
if url:
|
||||||
self.path = url
|
self.path = url
|
||||||
else:
|
else:
|
||||||
self.path = "http://%s/%s" % (self.host, path)
|
self.path = "http://{0}/{1}".format(self.host, path)
|
||||||
# Swap the actual host with the proxy.
|
# Swap the actual host with the proxy.
|
||||||
self.host = "%s:%d" % (httpProxyHost, httpProxyPort)
|
self.host = "{0}:{1}".format(httpProxyHost, httpProxyPort)
|
||||||
self.poolSize = poolSize
|
self.poolSize = poolSize
|
||||||
self.pool = []
|
self.pool = []
|
||||||
self.connectionPoolTimeout = connectionPoolTimeout
|
self.connectionPoolTimeout = connectionPoolTimeout
|
||||||
self.lock = thread.allocate_lock()
|
self.lock = threading.Lock()
|
||||||
self.schemeArgs = {}
|
self.schemeArgs = {}
|
||||||
if certKeyFile:
|
if certKeyFile:
|
||||||
self.schemeArgs['key_file'] = certKeyFile
|
self.schemeArgs['key_file'] = certKeyFile
|
||||||
@@ -1207,7 +1217,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
|
|
||||||
headers = {'Cookie' : self.cookie,
|
headers = {'Cookie' : self.cookie,
|
||||||
'SOAPAction' : self.versionId,
|
'SOAPAction' : self.versionId,
|
||||||
'Content-Type' : 'text/xml; charset=%s' % XML_ENCODING}
|
'Content-Type': 'text/xml; charset={0}'.format(XML_ENCODING)}
|
||||||
if self._acceptCompressedResponses:
|
if self._acceptCompressedResponses:
|
||||||
headers['Accept-Encoding'] = 'gzip, deflate'
|
headers['Accept-Encoding'] = 'gzip, deflate'
|
||||||
req = self.SerializeRequest(mo, info, args)
|
req = self.SerializeRequest(mo, info, args)
|
||||||
@@ -1251,7 +1261,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
raise obj # pylint: disable-msg=E0702
|
raise obj # pylint: disable-msg=E0702
|
||||||
else:
|
else:
|
||||||
conn.close()
|
conn.close()
|
||||||
raise http_client.HTTPException("%d %s" % (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
|
||||||
# SoapStubAdapter lock must be acquired before this method is called.
|
# SoapStubAdapter lock must be acquired before this method is called.
|
||||||
@@ -1384,14 +1394,14 @@ class SoapCmdStubAdapter(SoapStubAdapterBase):
|
|||||||
(outText, errText) = p.communicate(req)
|
(outText, errText) = p.communicate(req)
|
||||||
if p.returncode < 0:
|
if p.returncode < 0:
|
||||||
# Process died with a signal
|
# Process died with a signal
|
||||||
errText = "Process terminated with signal %d\n%s" % (-p.returncode, errText)
|
errText = "Process terminated with signal {0}\n{1}".format(-p.returncode, errText)
|
||||||
raise self.systemError(msg=errText, reason=errText)
|
raise self.systemError(msg=errText, reason=errText)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
(responseHeaders, responseBody) = ParseHttpResponse(outText)
|
(responseHeaders, responseBody) = ParseHttpResponse(outText)
|
||||||
obj = SoapResponseDeserializer(self).Deserialize(responseBody, info.result)
|
obj = SoapResponseDeserializer(self).Deserialize(responseBody, info.result)
|
||||||
except:
|
except:
|
||||||
errText = "Failure parsing SOAP response (%s)\n%s" % (outText, errText)
|
errText = "Failure parsing SOAP response ({0})\n{1}}".format(outText, errText)
|
||||||
raise self.systemError(msg=errText, reason=errText)
|
raise self.systemError(msg=errText, reason=errText)
|
||||||
|
|
||||||
if p.returncode == 0:
|
if p.returncode == 0:
|
||||||
@@ -1491,7 +1501,7 @@ class SessionOrientedStub(StubAdapterBase):
|
|||||||
raise obj
|
raise obj
|
||||||
|
|
||||||
# Raise any socket/httplib errors caught above.
|
# Raise any socket/httplib errors caught above.
|
||||||
raise
|
raise SystemError()
|
||||||
|
|
||||||
## Retrieve a managed property
|
## Retrieve a managed property
|
||||||
#
|
#
|
||||||
@@ -1513,7 +1523,7 @@ class SessionOrientedStub(StubAdapterBase):
|
|||||||
time.sleep(self.retryDelay)
|
time.sleep(self.retryDelay)
|
||||||
retriesLeft -= 1
|
retriesLeft -= 1
|
||||||
continue
|
continue
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if isinstance(e, self.SESSION_EXCEPTIONS):
|
if isinstance(e, self.SESSION_EXCEPTIONS):
|
||||||
# Our session might've timed out, change our state and retry.
|
# Our session might've timed out, change our state and retry.
|
||||||
self._SetStateUnauthenticated()
|
self._SetStateUnauthenticated()
|
||||||
@@ -1521,7 +1531,7 @@ class SessionOrientedStub(StubAdapterBase):
|
|||||||
raise e
|
raise e
|
||||||
return obj
|
return obj
|
||||||
# Raise any socket/httplib errors caught above.
|
# Raise any socket/httplib errors caught above.
|
||||||
raise
|
raise SystemError()
|
||||||
|
|
||||||
## Handle the login method call
|
## Handle the login method call
|
||||||
#
|
#
|
||||||
|
@@ -12,8 +12,8 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import absolute_import
|
||||||
from VmomiSupport import GetVmodlType
|
from pyVmomi.VmomiSupport import GetVmodlType
|
||||||
|
|
||||||
class StubAdapterAccessorMixin:
|
class StubAdapterAccessorMixin:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@@ -12,8 +12,8 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import absolute_import
|
||||||
from VmomiSupport import nsMap, versionMap, versionIdMap, serviceNsMap, parentMap
|
from pyVmomi.VmomiSupport import nsMap, versionMap, versionIdMap, serviceNsMap, parentMap
|
||||||
|
|
||||||
## Add an API version
|
## Add an API version
|
||||||
def AddVersion(version, ns, versionId='', isLegacy=0, serviceNs=''):
|
def AddVersion(version, ns, versionId='', isLegacy=0, serviceNs=''):
|
||||||
|
@@ -14,21 +14,34 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
## VMOMI support code
|
## VMOMI support code
|
||||||
|
from __future__ import absolute_import
|
||||||
from __future__ import with_statement # 2.5 only
|
from __future__ import with_statement # 2.5 only
|
||||||
|
|
||||||
|
from six import iteritems
|
||||||
|
from six import iterkeys
|
||||||
|
from six import itervalues
|
||||||
|
from six import text_type
|
||||||
|
from six import PY3
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import Iso8601
|
import pyVmomi.Iso8601
|
||||||
import base64
|
import base64
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
# python3 removed long, it's the same as int
|
||||||
|
long = int
|
||||||
|
# python3 removed basestring, use str instead.
|
||||||
|
basestring = str
|
||||||
|
|
||||||
NoneType = type(None)
|
NoneType = type(None)
|
||||||
try:
|
try:
|
||||||
from pyVmomiSettings import allowGetSet
|
from pyVmomi.pyVmomiSettings import allowGetSet
|
||||||
_allowGetSet = allowGetSet
|
_allowGetSet = allowGetSet
|
||||||
except:
|
except:
|
||||||
_allowGetSet = True
|
_allowGetSet = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from pyVmomiSettings import allowCapitalizedNames
|
from pyVmomi.pyVmomiSettings import allowCapitalizedNames
|
||||||
_allowCapitalizedNames = allowCapitalizedNames
|
_allowCapitalizedNames = allowCapitalizedNames
|
||||||
except:
|
except:
|
||||||
_allowCapitalizedNames = True
|
_allowCapitalizedNames = True
|
||||||
@@ -176,13 +189,13 @@ class LazyObject(Object):
|
|||||||
else:
|
else:
|
||||||
raise AttributeError(attr)
|
raise AttributeError(attr)
|
||||||
|
|
||||||
class Link(unicode):
|
class Link(text_type):
|
||||||
def __new__(cls, obj):
|
def __new__(cls, obj):
|
||||||
if isinstance(obj, basestring):
|
if isinstance(obj, basestring):
|
||||||
return unicode.__new__(cls, obj)
|
return text_type.__new__(cls, obj)
|
||||||
elif isinstance(obj, DataObject):
|
elif isinstance(obj, DataObject):
|
||||||
if obj.key:
|
if obj.key:
|
||||||
return unicode.__new__(cls, obj.key)
|
return text_type.__new__(cls, obj.key)
|
||||||
raise AttributeError("DataObject does not have a key to link")
|
raise AttributeError("DataObject does not have a key to link")
|
||||||
else:
|
else:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
@@ -348,7 +361,7 @@ class ManagedObject(object):
|
|||||||
args = list(posargs) + [None] * (len(info.params) - len(posargs))
|
args = list(posargs) + [None] * (len(info.params) - len(posargs))
|
||||||
if len(kwargs) > 0:
|
if len(kwargs) > 0:
|
||||||
paramNames = [param.name for param in info.params]
|
paramNames = [param.name for param in info.params]
|
||||||
for (k, v) in kwargs.items():
|
for (k, v) in list(kwargs.items()):
|
||||||
try:
|
try:
|
||||||
idx = paramNames.index(k)
|
idx = paramNames.index(k)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -1026,7 +1039,7 @@ def GetWsdlTypes():
|
|||||||
with _lazyLock:
|
with _lazyLock:
|
||||||
for ns, name in _wsdlDefMap:
|
for ns, name in _wsdlDefMap:
|
||||||
GetWsdlType(ns, name)
|
GetWsdlType(ns, name)
|
||||||
return _wsdlTypeMap.itervalues()
|
return itervalues(_wsdlTypeMap)
|
||||||
|
|
||||||
## Get the qualified XML schema name (ns, name) of a type
|
## Get the qualified XML schema name (ns, name) of a type
|
||||||
def GetQualifiedWsdlName(type):
|
def GetQualifiedWsdlName(type):
|
||||||
@@ -1113,21 +1126,21 @@ def GetServiceVersions(namespace):
|
|||||||
by compatibility (i.e. any version in the list that is compatible with some version
|
by compatibility (i.e. any version in the list that is compatible with some version
|
||||||
v in the list will preceed v)
|
v in the list will preceed v)
|
||||||
"""
|
"""
|
||||||
versions = dict((v, True) for (v, n) in serviceNsMap.iteritems() if n == namespace)
|
versions = dict((v, True) for (v, n) in iteritems(serviceNsMap) if n == namespace)
|
||||||
mappings = {}
|
mappings = {}
|
||||||
for v in versions.iterkeys():
|
for v in iterkeys(versions):
|
||||||
mappings[v] = set(parent for parent in parentMap[v].iterkeys()
|
mappings[v] = set(parent for parent in iterkeys(parentMap[v])
|
||||||
if parent != v and versions.has_key(parent))
|
if parent != v and parent in versions.keys())
|
||||||
res = []
|
res = []
|
||||||
while True:
|
while True:
|
||||||
el = [ k for (k, v) in mappings.iteritems() if len(v) == 0 ]
|
el = [ k for (k, v) in iteritems(mappings) if len(v) == 0 ]
|
||||||
if len(el) == 0:
|
if len(el) == 0:
|
||||||
return res
|
return res
|
||||||
el.sort()
|
el.sort()
|
||||||
for k in el:
|
for k in el:
|
||||||
res.insert(0, k)
|
res.insert(0, k)
|
||||||
del mappings[k]
|
del mappings[k]
|
||||||
for values in mappings.itervalues():
|
for values in itervalues(mappings):
|
||||||
values.discard(k)
|
values.discard(k)
|
||||||
|
|
||||||
|
|
||||||
@@ -1218,7 +1231,7 @@ def GetCompatibleType(type, version):
|
|||||||
|
|
||||||
## Invert an injective mapping
|
## Invert an injective mapping
|
||||||
def InverseMap(map):
|
def InverseMap(map):
|
||||||
return dict([ (v, k) for (k, v) in map.iteritems() ])
|
return dict([ (v, k) for (k, v) in iteritems(map) ])
|
||||||
|
|
||||||
types = Object()
|
types = Object()
|
||||||
nsMap = {}
|
nsMap = {}
|
||||||
@@ -1227,7 +1240,7 @@ versionMap = {}
|
|||||||
serviceNsMap = { BASE_VERSION : XMLNS_VMODL_BASE.split(":")[-1] }
|
serviceNsMap = { BASE_VERSION : XMLNS_VMODL_BASE.split(":")[-1] }
|
||||||
parentMap = {}
|
parentMap = {}
|
||||||
|
|
||||||
from Version import AddVersion, IsChildVersion
|
from pyVmomi.Version import AddVersion, IsChildVersion
|
||||||
|
|
||||||
if not isinstance(bool, type): # bool not a type in python <= 2.2
|
if not isinstance(bool, type): # bool not a type in python <= 2.2
|
||||||
bool = type("bool", (int,),
|
bool = type("bool", (int,),
|
||||||
@@ -1237,7 +1250,7 @@ short = type("short", (int,), {})
|
|||||||
double = type("double", (float,), {})
|
double = type("double", (float,), {})
|
||||||
URI = type("URI", (str,), {})
|
URI = type("URI", (str,), {})
|
||||||
binary = type("binary", (str,), {})
|
binary = type("binary", (str,), {})
|
||||||
PropertyPath = type("PropertyPath", (unicode,), {})
|
PropertyPath = type("PropertyPath", (text_type,), {})
|
||||||
|
|
||||||
# _wsdlTypeMapNSs store namespaces added to _wsdlTypeMap in _SetWsdlType
|
# _wsdlTypeMapNSs store namespaces added to _wsdlTypeMap in _SetWsdlType
|
||||||
_wsdlTypeMapNSs = set()
|
_wsdlTypeMapNSs = set()
|
||||||
@@ -1263,7 +1276,7 @@ _wsdlTypeMap = {
|
|||||||
}
|
}
|
||||||
_wsdlNameMap = InverseMap(_wsdlTypeMap)
|
_wsdlNameMap = InverseMap(_wsdlTypeMap)
|
||||||
|
|
||||||
for ((ns, name), typ) in _wsdlTypeMap.items():
|
for ((ns, name), typ) in iteritems(dict(_wsdlTypeMap)):
|
||||||
if typ is not NoneType:
|
if typ is not NoneType:
|
||||||
setattr(types, typ.__name__, typ)
|
setattr(types, typ.__name__, typ)
|
||||||
_wsdlTypeMapNSs.add(ns)
|
_wsdlTypeMapNSs.add(ns)
|
||||||
@@ -1277,8 +1290,8 @@ del name, typ
|
|||||||
|
|
||||||
# unicode is mapped to wsdl name 'string' (Cannot put in wsdlTypeMap or name
|
# unicode is mapped to wsdl name 'string' (Cannot put in wsdlTypeMap or name
|
||||||
# collision with non-unicode string)
|
# collision with non-unicode string)
|
||||||
_wsdlNameMap[unicode] = (XMLNS_XSD, 'string')
|
_wsdlNameMap[text_type] = (XMLNS_XSD, 'string')
|
||||||
_wsdlNameMap[CreateArrayType(unicode)] = (XMLNS_VMODL_BASE, 'ArrayOfString')
|
_wsdlNameMap[CreateArrayType(text_type)] = (XMLNS_VMODL_BASE, 'ArrayOfString')
|
||||||
|
|
||||||
# _wsdlMethodNSs store namespaces added to _wsdlMethodMap in _SetWsdlMethod
|
# _wsdlMethodNSs store namespaces added to _wsdlMethodMap in _SetWsdlMethod
|
||||||
_wsdlMethodNSs = set()
|
_wsdlMethodNSs = set()
|
||||||
@@ -1322,7 +1335,7 @@ vmodlTypes = {
|
|||||||
vmodlNames = {}
|
vmodlNames = {}
|
||||||
|
|
||||||
## Add array type into special names
|
## Add array type into special names
|
||||||
for name, typ in vmodlTypes.copy().iteritems():
|
for name, typ in vmodlTypes.copy().items():
|
||||||
if typ is not NoneType:
|
if typ is not NoneType:
|
||||||
try:
|
try:
|
||||||
arrayType = typ.Array
|
arrayType = typ.Array
|
||||||
@@ -1454,7 +1467,7 @@ class StringDict(dict):
|
|||||||
|
|
||||||
# Same as dict setdefault, except this will call through our __setitem__
|
# Same as dict setdefault, except this will call through our __setitem__
|
||||||
def update(self, *args, **kwargs):
|
def update(self, *args, **kwargs):
|
||||||
for k, v in dict(*args, **kwargs).iteritems():
|
for k, v in iteritems(dict(*args, **kwargs)):
|
||||||
self[k] = v
|
self[k] = v
|
||||||
|
|
||||||
# Same as dict setdefault, except this will call through our __setitem__
|
# Same as dict setdefault, except this will call through our __setitem__
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import absolute_import
|
||||||
# In VmomiSupport, to support dynamic type loading, all the data types are
|
# In VmomiSupport, to support dynamic type loading, all the data types are
|
||||||
# wrapped around using a meta type which can intercept attribute access and
|
# wrapped around using a meta type which can intercept attribute access and
|
||||||
# load the necessary nested classes. This can be implemented only in python 2.5
|
# load the necessary nested classes. This can be implemented only in python 2.5
|
||||||
@@ -22,170 +22,170 @@ if sys.version_info < (2,5):
|
|||||||
sys.stderr.write("You need Python 2.5 or later to import pyVmomi module\n")
|
sys.stderr.write("You need Python 2.5 or later to import pyVmomi module\n")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
import VmomiSupport
|
import pyVmomi.VmomiSupport
|
||||||
import CoreTypes
|
import pyVmomi.CoreTypes
|
||||||
try:
|
try:
|
||||||
import ReflectTypes
|
import ReflectTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import ServerObjects
|
import pyVmomi.ServerObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import InternalServerObjects
|
import pyVmomi.InternalServerObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Import all the known product-specific types
|
# Import all the known product-specific types
|
||||||
# XXX: Make this search the package for types?
|
# XXX: Make this search the package for types?
|
||||||
try:
|
try:
|
||||||
import DrObjects
|
import pyVmomi.DrObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import DrextObjects
|
import pyVmomi.DrextObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import HbrReplicaTypes
|
import pyVmomi.HbrReplicaTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import HmsObjects
|
import pyVmomi.HmsObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import HostdObjects
|
import pyVmomi.HostdObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import VpxObjects
|
import pyVmomi.VpxObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import VorbTypes
|
import pyVmomi.VorbTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import DodoTypes
|
import pyVmomi.DodoTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import VmwauthproxyTypes
|
import pyVmomi.VmwauthproxyTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import DmsTypes
|
import pyVmomi.DmsTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import OmsTypes
|
import pyVmomi.OmsTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import HmoTypes
|
import pyVmomi.HmoTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import CimsfccTypes
|
import pyVmomi.CimsfccTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import TaskupdaterTypes
|
import pyVmomi.TaskupdaterTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import ImgFactTypes
|
import pyVmomi.ImgFactTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import VpxapiTypes
|
import pyVmomi.VpxapiTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
import CsiObjects
|
import pyVmomi.CsiObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import HostdTypes
|
import pyVmomi.HostdTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import TaggingObjects
|
import pyVmomi.TaggingObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import NfcTypes
|
import pyVmomi.NfcTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import SmsObjects
|
import pyVmomi.SmsObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import SpsObjects
|
import pyVmomi.SpsObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import DataserviceObjects
|
import pyVmomi.DataserviceObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Start of update manager specific types
|
# Start of update manager specific types
|
||||||
try:
|
try:
|
||||||
import IntegrityObjects
|
import pyVmomi.IntegrityObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import SysimageObjects
|
import pyVmomi.SysimageObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
# End of update manager specific types
|
# End of update manager specific types
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import RbdTypes
|
import pyVmomi.RbdTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Import Profile based management specific VMODL
|
# Import Profile based management specific VMODL
|
||||||
try:
|
try:
|
||||||
import PbmObjects
|
import pyVmomi.PbmObjects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import CisLicenseTypes
|
import pyVmomi.CisLicenseTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import TestTypes
|
import pyVmomi.TestTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import SsoTypes
|
import pyVmomi.SsoTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import CisCmTypes
|
import pyVmomi.CisCmTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import DataserviceTypes
|
import pyVmomi.DataserviceTypes
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -194,18 +194,18 @@ except ImportError:
|
|||||||
# As well load it proactively.
|
# As well load it proactively.
|
||||||
# Note: This should be done before importing SoapAdapter as it uses
|
# Note: This should be done before importing SoapAdapter as it uses
|
||||||
# some fault types
|
# some fault types
|
||||||
VmomiSupport.GetVmodlType("vmodl.DynamicData")
|
pyVmomi.VmomiSupport.GetVmodlType("vmodl.DynamicData")
|
||||||
|
|
||||||
from SoapAdapter import SoapStubAdapter, StubAdapterBase, SoapCmdStubAdapter, \
|
from pyVmomi.SoapAdapter import SoapStubAdapter, StubAdapterBase, SoapCmdStubAdapter, \
|
||||||
SessionOrientedStub
|
SessionOrientedStub
|
||||||
|
|
||||||
types = VmomiSupport.types
|
types = pyVmomi.VmomiSupport.types
|
||||||
|
|
||||||
# This will allow files to use Create** functions
|
# This will allow files to use Create** functions
|
||||||
# directly from pyVmomi
|
# directly from pyVmomi
|
||||||
CreateEnumType = VmomiSupport.CreateEnumType
|
CreateEnumType = pyVmomi.VmomiSupport.CreateEnumType
|
||||||
CreateDataType = VmomiSupport.CreateDataType
|
CreateDataType = pyVmomi.VmomiSupport.CreateDataType
|
||||||
CreateManagedType = VmomiSupport.CreateManagedType
|
CreateManagedType = pyVmomi.VmomiSupport.CreateManagedType
|
||||||
|
|
||||||
# For all the top level names, creating a LazyModule object
|
# For all the top level names, creating a LazyModule object
|
||||||
# in the global namespace of pyVmomi. Files can just import the
|
# in the global namespace of pyVmomi. Files can just import the
|
||||||
@@ -214,14 +214,14 @@ CreateManagedType = VmomiSupport.CreateManagedType
|
|||||||
# ALLOWED: from pyVmomi import vim
|
# ALLOWED: from pyVmomi import vim
|
||||||
# NOT ALLOWED: from pyVmomi import vim.host
|
# NOT ALLOWED: from pyVmomi import vim.host
|
||||||
_globals = globals()
|
_globals = globals()
|
||||||
for name in VmomiSupport._topLevelNames:
|
for name in pyVmomi.VmomiSupport._topLevelNames:
|
||||||
upperCaseName = VmomiSupport.Capitalize(name)
|
upperCaseName = pyVmomi.VmomiSupport.Capitalize(name)
|
||||||
obj = VmomiSupport.LazyModule(name)
|
obj = pyVmomi.VmomiSupport.LazyModule(name)
|
||||||
_globals[name] = obj
|
_globals[name] = obj
|
||||||
if VmomiSupport._allowCapitalizedNames:
|
if pyVmomi.VmomiSupport._allowCapitalizedNames:
|
||||||
_globals[upperCaseName] = obj
|
_globals[upperCaseName] = obj
|
||||||
if not hasattr(VmomiSupport.types, name):
|
if not hasattr(pyVmomi.VmomiSupport.types, name):
|
||||||
setattr(VmomiSupport.types, name, obj)
|
setattr(pyVmomi.VmomiSupport.types, name, obj)
|
||||||
if VmomiSupport._allowCapitalizedNames:
|
if pyVmomi.VmomiSupport._allowCapitalizedNames:
|
||||||
setattr(VmomiSupport.types, upperCaseName, obj)
|
setattr(pyVmomi.VmomiSupport.types, upperCaseName, obj)
|
||||||
del _globals
|
del _globals
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# VMware vSphere Python SDK
|
# VMware vSphere Python SDK
|
||||||
# Copyright (c) 2008-2014 VMware, Inc. All Rights Reserved.
|
# Copyright (c) 2008-2013 VMware, Inc. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -18,36 +18,48 @@
|
|||||||
Python program for listing the vms on an ESX / vCenter host
|
Python program for listing the vms on an ESX / vCenter host
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from optparse import OptionParser, make_option
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import pyVmomi
|
||||||
|
|
||||||
|
from pyVmomi import vim
|
||||||
|
from pyVmomi import vmodl
|
||||||
|
|
||||||
from pyVim.connect import SmartConnect, Disconnect
|
from pyVim.connect import SmartConnect, Disconnect
|
||||||
from pyVmomi import vmodl
|
from pyVmomi import vmodl
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import atexit
|
import atexit
|
||||||
import getpass
|
import getpass
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def GetArgs():
|
def GetArgs():
|
||||||
"""
|
"""
|
||||||
Supports the command-line arguments listed below.
|
Supports the command-line arguments listed below.
|
||||||
"""
|
"""
|
||||||
parser = argparse.ArgumentParser(description='Process args for retrieving all the Virtual Machines')
|
parser = argparse.ArgumentParser(
|
||||||
parser.add_argument('-s', '--host', required=True, action='store', help='Remote host to connect to')
|
description='Process args for retrieving all the Virtual Machines')
|
||||||
parser.add_argument('-o', '--port', type=int, default=443, action='store', help='Port to connect on')
|
parser.add_argument('-s', '--host', required=True, action='store',
|
||||||
parser.add_argument('-u', '--user', required=True, action='store', help='User name to use when connecting to host')
|
help='Remote host to connect to')
|
||||||
parser.add_argument('-p', '--password', required=False, action='store', help='Password to use when connecting to host')
|
parser.add_argument('-o', '--port', type=int, default=443, action='store',
|
||||||
|
help='Port to connect on')
|
||||||
|
parser.add_argument('-u', '--user', required=True, action='store',
|
||||||
|
help='User name to use when connecting to host')
|
||||||
|
parser.add_argument('-p', '--password', required=False, action='store',
|
||||||
|
help='Password to use when connecting to host')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
||||||
def PrintVmInfo(vm, depth=1):
|
def PrintVmInfo(vm, depth=1):
|
||||||
"""
|
"""
|
||||||
Print information for a particular virtual machine or recurse into a folder with depth protection
|
Print information for a particular virtual machine or recurse into a folder
|
||||||
|
with depth protection
|
||||||
"""
|
"""
|
||||||
maxdepth = 10
|
maxdepth = 10
|
||||||
|
|
||||||
# if this is a group it will have children. if it does, recurse into them and then return
|
# if this is a group it will have children. if it does, recurse into them
|
||||||
|
# and then return
|
||||||
if hasattr(vm, 'childEntity'):
|
if hasattr(vm, 'childEntity'):
|
||||||
if depth > maxdepth:
|
if depth > maxdepth:
|
||||||
return
|
return
|
||||||
@@ -57,23 +69,20 @@ def PrintVmInfo(vm, depth=1):
|
|||||||
return
|
return
|
||||||
|
|
||||||
summary = vm.summary
|
summary = vm.summary
|
||||||
print "Name : ", summary.config.name
|
print("Name : ", summary.config.name)
|
||||||
print "Path : ", summary.config.vmPathName
|
print("Path : ", summary.config.vmPathName)
|
||||||
print "Guest : ", summary.config.guestFullName
|
print("Guest : ", summary.config.guestFullName)
|
||||||
print "Instance UUID : ", vm.summary.config.instanceUuid
|
|
||||||
print "BIOS UUID : ", vm.summary.config.uuid
|
|
||||||
|
|
||||||
annotation = summary.config.annotation
|
annotation = summary.config.annotation
|
||||||
if annotation != None and annotation != "":
|
if annotation != None and annotation != "":
|
||||||
print "Annotation : ", annotation
|
print("Annotation : ", annotation)
|
||||||
print "State : ", summary.runtime.powerState
|
print("State : ", summary.runtime.powerState)
|
||||||
if summary.guest != None:
|
if summary.guest != None:
|
||||||
ip = summary.guest.ipAddress
|
ip = summary.guest.ipAddress
|
||||||
if ip != None and ip != "":
|
if ip != None and ip != "":
|
||||||
print "IP : ", ip
|
print("IP : ", ip)
|
||||||
if summary.runtime.question != None:
|
if summary.runtime.question != None:
|
||||||
print "Question : ", summary.runtime.question.text
|
print("Question : ", summary.runtime.question.text)
|
||||||
print ""
|
print("")
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""
|
"""
|
||||||
@@ -84,36 +93,28 @@ def main():
|
|||||||
if args.password:
|
if args.password:
|
||||||
password = args.password
|
password = args.password
|
||||||
else:
|
else:
|
||||||
password = getpass.getpass(prompt='Enter password for host %s and user %s: ' % (args.host,args.user))
|
password = getpass.getpass(prompt='Enter password for host %s and '
|
||||||
|
'user %s: ' % (args.host,args.user))
|
||||||
|
|
||||||
try:
|
|
||||||
si = None
|
|
||||||
try:
|
|
||||||
si = SmartConnect(host=args.host,
|
si = SmartConnect(host=args.host,
|
||||||
user=args.user,
|
user=args.user,
|
||||||
pwd=password,
|
pwd=password,
|
||||||
port=int(args.port))
|
port=int(args.port))
|
||||||
except IOError, e:
|
|
||||||
pass
|
|
||||||
if not si:
|
if not si:
|
||||||
print "Could not connect to the specified host using specified username and password"
|
print("Could not connect to the specified host using specified "
|
||||||
|
"username and password")
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
atexit.register(Disconnect, si)
|
atexit.register(Disconnect, si)
|
||||||
|
|
||||||
content = si.RetrieveContent()
|
content = si.RetrieveContent()
|
||||||
datacenter = content.rootFolder.childEntity[0]
|
for child in content.rootFolder.childEntity:
|
||||||
|
if hasattr(child, 'vmFolder'):
|
||||||
|
datacenter = child
|
||||||
vmFolder = datacenter.vmFolder
|
vmFolder = datacenter.vmFolder
|
||||||
vmList = vmFolder.childEntity
|
vmList = vmFolder.childEntity
|
||||||
for vm in vmList:
|
for vm in vmList:
|
||||||
PrintVmInfo(vm)
|
PrintVmInfo(vm)
|
||||||
except vmodl.MethodFault, e:
|
|
||||||
print "Caught vmodl fault : " + e.msg
|
|
||||||
return -1
|
|
||||||
except Exception, e:
|
|
||||||
print "Caught exception : " + str(e)
|
|
||||||
return -1
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# Start program
|
# Start program
|
||||||
|
@@ -19,6 +19,8 @@
|
|||||||
Python program for powering on vms on a host on which hostd is running
|
Python program for powering on vms on a host on which hostd is running
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from pyVim.connect import SmartConnect, Disconnect
|
from pyVim.connect import SmartConnect, Disconnect
|
||||||
from pyVmomi import vim, vmodl
|
from pyVmomi import vim, vmodl
|
||||||
|
|
||||||
@@ -107,7 +109,7 @@ def main():
|
|||||||
try:
|
try:
|
||||||
vmnames = args.vmname
|
vmnames = args.vmname
|
||||||
if not len(vmnames):
|
if not len(vmnames):
|
||||||
print "No virtual machine specified for poweron"
|
print("No virtual machine specified for poweron")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
si = None
|
si = None
|
||||||
@@ -116,10 +118,10 @@ def main():
|
|||||||
user=args.user,
|
user=args.user,
|
||||||
pwd=password,
|
pwd=password,
|
||||||
port=int(args.port))
|
port=int(args.port))
|
||||||
except IOError, e:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
if not si:
|
if not si:
|
||||||
print "Cannot connect to specified host using specified username and password"
|
print("Cannot connect to specified host using specified username and password")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
atexit.register(Disconnect, si)
|
atexit.register(Disconnect, si)
|
||||||
@@ -139,11 +141,11 @@ def main():
|
|||||||
# Wait for power on to complete
|
# Wait for power on to complete
|
||||||
WaitForTasks(tasks, si)
|
WaitForTasks(tasks, si)
|
||||||
|
|
||||||
print "Virtual Machine(s) have been powered on successfully"
|
print("Virtual Machine(s) have been powered on successfully")
|
||||||
except vmodl.MethodFault, e:
|
except vmodl.MethodFault as e:
|
||||||
print "Caught vmodl fault : " + e.msg
|
print("Caught vmodl fault : " + e.msg)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
print "Caught Exception : " + str(e)
|
print("Caught Exception : " + str(e))
|
||||||
|
|
||||||
# Start program
|
# Start program
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
mock
|
contextdecorator
|
||||||
PyYAML>=3.11
|
PyYAML>=3.11
|
||||||
testtools>=0.9.34
|
testtools>=0.9.34
|
||||||
vcrpy>=1.0.2
|
vcrpy
|
||||||
|
265
tests/fixtures/smart_connection.yaml
vendored
Normal file
265
tests/fixtures/smart_connection.yaml
vendored
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: null
|
||||||
|
headers:
|
||||||
|
Connection: [close]
|
||||||
|
Host: ['vcsa:443']
|
||||||
|
User-Agent: [Python-urllib/2.7]
|
||||||
|
method: GET
|
||||||
|
uri: https://vcsa:443//sdk/vimServiceVersions.xml
|
||||||
|
response:
|
||||||
|
body: {string: !!python/unicode "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!--\n
|
||||||
|
\ Copyright 2008-2012 VMware, Inc. All rights reserved.\n-->\n<namespaces
|
||||||
|
version=\"1.0\">\n <namespace>\n <name>urn:vim25</name>\n <version>5.5</version>\n
|
||||||
|
\ <priorVersions>\n <version>5.1</version>\n <version>5.0</version>\n
|
||||||
|
\ <version>4.1</version>\n <version>4.0</version>\n <version>2.5u2</version>\n
|
||||||
|
\ <version>2.5</version>\n </priorVersions>\n </namespace>\n <namespace>\n
|
||||||
|
\ <name>urn:vim2</name>\n <version>2.0</version>\n </namespace>\n</namespaces>\n"}
|
||||||
|
headers:
|
||||||
|
connection: [close]
|
||||||
|
content-length: ['530']
|
||||||
|
content-type: [text/xml]
|
||||||
|
date: ['Wed, 23 Jul 2014 21:21:18 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?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><RetrieveServiceContent xmlns="urn:vim25"><_this type="ServiceInstance">ServiceInstance</_this></RetrieveServiceContent></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: ['']
|
||||||
|
SOAPAction: ['"urn:vim25/5.5"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: !!python/unicode "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<RetrieveServiceContentResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><rootFolder type=\"Folder\">group-d1</rootFolder><propertyCollector
|
||||||
|
type=\"PropertyCollector\">propertyCollector</propertyCollector><viewManager
|
||||||
|
type=\"ViewManager\">ViewManager</viewManager><about><name>VMware vCenter
|
||||||
|
Server</name><fullName>VMware vCenter Server 5.5.0 build-1750787 (Sim)</fullName><vendor>VMware,
|
||||||
|
Inc.</vendor><version>5.5.0</version><build>1750787 (Sim)</build><localeVersion>INTL</localeVersion><localeBuild>000</localeBuild><osType>linux-x64</osType><productLineId>vpx</productLineId><apiType>VirtualCenter</apiType><apiVersion>5.5</apiVersion><instanceUuid>EAB4D846-C243-426B-A021-0547644CE59D</instanceUuid><licenseProductName>VMware
|
||||||
|
VirtualCenter Server</licenseProductName><licenseProductVersion>5.0</licenseProductVersion></about><setting
|
||||||
|
type=\"OptionManager\">VpxSettings</setting><userDirectory type=\"UserDirectory\">UserDirectory</userDirectory><sessionManager
|
||||||
|
type=\"SessionManager\">SessionManager</sessionManager><authorizationManager
|
||||||
|
type=\"AuthorizationManager\">AuthorizationManager</authorizationManager><serviceManager
|
||||||
|
type=\"ServiceManager\">ServiceMgr</serviceManager><perfManager type=\"PerformanceManager\">PerfMgr</perfManager><scheduledTaskManager
|
||||||
|
type=\"ScheduledTaskManager\">ScheduledTaskManager</scheduledTaskManager><alarmManager
|
||||||
|
type=\"AlarmManager\">AlarmManager</alarmManager><eventManager type=\"EventManager\">EventManager</eventManager><taskManager
|
||||||
|
type=\"TaskManager\">TaskManager</taskManager><extensionManager type=\"ExtensionManager\">ExtensionManager</extensionManager><customizationSpecManager
|
||||||
|
type=\"CustomizationSpecManager\">CustomizationSpecManager</customizationSpecManager><customFieldsManager
|
||||||
|
type=\"CustomFieldsManager\">CustomFieldsManager</customFieldsManager><diagnosticManager
|
||||||
|
type=\"DiagnosticManager\">DiagMgr</diagnosticManager><licenseManager type=\"LicenseManager\">LicenseManager</licenseManager><searchIndex
|
||||||
|
type=\"SearchIndex\">SearchIndex</searchIndex><fileManager type=\"FileManager\">FileManager</fileManager><datastoreNamespaceManager
|
||||||
|
type=\"DatastoreNamespaceManager\">DatastoreNamespaceManager</datastoreNamespaceManager><virtualDiskManager
|
||||||
|
type=\"VirtualDiskManager\">virtualDiskManager</virtualDiskManager><snmpSystem
|
||||||
|
type=\"HostSnmpSystem\">SnmpSystem</snmpSystem><vmProvisioningChecker type=\"VirtualMachineProvisioningChecker\">ProvChecker</vmProvisioningChecker><vmCompatibilityChecker
|
||||||
|
type=\"VirtualMachineCompatibilityChecker\">CompatChecker</vmCompatibilityChecker><ovfManager
|
||||||
|
type=\"OvfManager\">OvfManager</ovfManager><ipPoolManager type=\"IpPoolManager\">IpPoolManager</ipPoolManager><dvSwitchManager
|
||||||
|
type=\"DistributedVirtualSwitchManager\">DVSManager</dvSwitchManager><hostProfileManager
|
||||||
|
type=\"HostProfileManager\">HostProfileManager</hostProfileManager><clusterProfileManager
|
||||||
|
type=\"ClusterProfileManager\">ClusterProfileManager</clusterProfileManager><complianceManager
|
||||||
|
type=\"ProfileComplianceManager\">MoComplianceManager</complianceManager><localizationManager
|
||||||
|
type=\"LocalizationManager\">LocalizationManager</localizationManager><storageResourceManager
|
||||||
|
type=\"StorageResourceManager\">StorageResourceManager</storageResourceManager><guestOperationsManager
|
||||||
|
type=\"GuestOperationsManager\">guestOperationsManager</guestOperationsManager></returnval></RetrieveServiceContentResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
cache-control: [no-cache]
|
||||||
|
connection: [Keep-Alive]
|
||||||
|
content-length: ['3611']
|
||||||
|
content-type: [text/xml; charset=utf-8]
|
||||||
|
date: ['Wed, 23 Jul 2014 21:21:18 GMT']
|
||||||
|
set-cookie: [vmware_soap_session="52773cd3-35c6-b40a-17f1-fe664a9f08f3"; Path=/;
|
||||||
|
HttpOnly; Secure;]
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?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><Login xmlns="urn:vim25"><_this type="SessionManager">SessionManager</_this><userName>my_user</userName><password>my_password</password></Login></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: [vmware_soap_session="52773cd3-35c6-b40a-17f1-fe664a9f08f3"; Path=/;
|
||||||
|
HttpOnly; Secure;]
|
||||||
|
SOAPAction: ['"urn:vim25/5.5"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: !!python/unicode "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<LoginResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><key>52773cd3-35c6-b40a-17f1-fe664a9f08f3</key><userName>root</userName><fullName>root
|
||||||
|
</fullName><loginTime>2014-07-23T21:21:18.297208Z</loginTime><lastActiveTime>2014-07-23T21:21:18.297208Z</lastActiveTime><locale>en</locale><messageLocale>en</messageLocale><extensionSession>false</extensionSession><ipAddress>172.16.16.1</ipAddress><userAgent></userAgent><callCount>0</callCount></returnval></LoginResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
cache-control: [no-cache]
|
||||||
|
connection: [Keep-Alive]
|
||||||
|
content-length: ['782']
|
||||||
|
content-type: [text/xml; charset=utf-8]
|
||||||
|
date: ['Wed, 23 Jul 2014 21:21:18 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?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><RetrieveServiceContent xmlns="urn:vim25"><_this type="ServiceInstance">ServiceInstance</_this></RetrieveServiceContent></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: [vmware_soap_session="52773cd3-35c6-b40a-17f1-fe664a9f08f3"; Path=/;
|
||||||
|
HttpOnly; Secure;]
|
||||||
|
SOAPAction: ['"urn:vim25/5.5"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: !!python/unicode "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<RetrieveServiceContentResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><rootFolder type=\"Folder\">group-d1</rootFolder><propertyCollector
|
||||||
|
type=\"PropertyCollector\">propertyCollector</propertyCollector><viewManager
|
||||||
|
type=\"ViewManager\">ViewManager</viewManager><about><name>VMware vCenter
|
||||||
|
Server</name><fullName>VMware vCenter Server 5.5.0 build-1750787 (Sim)</fullName><vendor>VMware,
|
||||||
|
Inc.</vendor><version>5.5.0</version><build>1750787 (Sim)</build><localeVersion>INTL</localeVersion><localeBuild>000</localeBuild><osType>linux-x64</osType><productLineId>vpx</productLineId><apiType>VirtualCenter</apiType><apiVersion>5.5</apiVersion><instanceUuid>EAB4D846-C243-426B-A021-0547644CE59D</instanceUuid><licenseProductName>VMware
|
||||||
|
VirtualCenter Server</licenseProductName><licenseProductVersion>5.0</licenseProductVersion></about><setting
|
||||||
|
type=\"OptionManager\">VpxSettings</setting><userDirectory type=\"UserDirectory\">UserDirectory</userDirectory><sessionManager
|
||||||
|
type=\"SessionManager\">SessionManager</sessionManager><authorizationManager
|
||||||
|
type=\"AuthorizationManager\">AuthorizationManager</authorizationManager><serviceManager
|
||||||
|
type=\"ServiceManager\">ServiceMgr</serviceManager><perfManager type=\"PerformanceManager\">PerfMgr</perfManager><scheduledTaskManager
|
||||||
|
type=\"ScheduledTaskManager\">ScheduledTaskManager</scheduledTaskManager><alarmManager
|
||||||
|
type=\"AlarmManager\">AlarmManager</alarmManager><eventManager type=\"EventManager\">EventManager</eventManager><taskManager
|
||||||
|
type=\"TaskManager\">TaskManager</taskManager><extensionManager type=\"ExtensionManager\">ExtensionManager</extensionManager><customizationSpecManager
|
||||||
|
type=\"CustomizationSpecManager\">CustomizationSpecManager</customizationSpecManager><customFieldsManager
|
||||||
|
type=\"CustomFieldsManager\">CustomFieldsManager</customFieldsManager><diagnosticManager
|
||||||
|
type=\"DiagnosticManager\">DiagMgr</diagnosticManager><licenseManager type=\"LicenseManager\">LicenseManager</licenseManager><searchIndex
|
||||||
|
type=\"SearchIndex\">SearchIndex</searchIndex><fileManager type=\"FileManager\">FileManager</fileManager><datastoreNamespaceManager
|
||||||
|
type=\"DatastoreNamespaceManager\">DatastoreNamespaceManager</datastoreNamespaceManager><virtualDiskManager
|
||||||
|
type=\"VirtualDiskManager\">virtualDiskManager</virtualDiskManager><snmpSystem
|
||||||
|
type=\"HostSnmpSystem\">SnmpSystem</snmpSystem><vmProvisioningChecker type=\"VirtualMachineProvisioningChecker\">ProvChecker</vmProvisioningChecker><vmCompatibilityChecker
|
||||||
|
type=\"VirtualMachineCompatibilityChecker\">CompatChecker</vmCompatibilityChecker><ovfManager
|
||||||
|
type=\"OvfManager\">OvfManager</ovfManager><ipPoolManager type=\"IpPoolManager\">IpPoolManager</ipPoolManager><dvSwitchManager
|
||||||
|
type=\"DistributedVirtualSwitchManager\">DVSManager</dvSwitchManager><hostProfileManager
|
||||||
|
type=\"HostProfileManager\">HostProfileManager</hostProfileManager><clusterProfileManager
|
||||||
|
type=\"ClusterProfileManager\">ClusterProfileManager</clusterProfileManager><complianceManager
|
||||||
|
type=\"ProfileComplianceManager\">MoComplianceManager</complianceManager><localizationManager
|
||||||
|
type=\"LocalizationManager\">LocalizationManager</localizationManager><storageResourceManager
|
||||||
|
type=\"StorageResourceManager\">StorageResourceManager</storageResourceManager><guestOperationsManager
|
||||||
|
type=\"GuestOperationsManager\">guestOperationsManager</guestOperationsManager></returnval></RetrieveServiceContentResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
cache-control: [no-cache]
|
||||||
|
connection: [Keep-Alive]
|
||||||
|
content-length: ['3611']
|
||||||
|
content-type: [text/xml; charset=utf-8]
|
||||||
|
date: ['Wed, 23 Jul 2014 21:21:18 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?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><RetrievePropertiesEx xmlns="urn:vim25"><_this type="PropertyCollector">propertyCollector</_this><specSet><propSet><type>ServiceInstance</type><all>false</all><pathSet>content</pathSet></propSet><objectSet><obj
|
||||||
|
type="ServiceInstance">ServiceInstance</obj><skip>false</skip></objectSet></specSet><options><maxObjects>1</maxObjects></options></RetrievePropertiesEx></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: [vmware_soap_session="52773cd3-35c6-b40a-17f1-fe664a9f08f3"; Path=/;
|
||||||
|
HttpOnly; Secure;]
|
||||||
|
SOAPAction: ['"urn:vim25/5.5"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: !!python/unicode "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<RetrievePropertiesExResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><objects><obj type=\"ServiceInstance\">ServiceInstance</obj><propSet><name>content</name><val
|
||||||
|
xsi:type=\"ServiceContent\"><rootFolder type=\"Folder\">group-d1</rootFolder><propertyCollector
|
||||||
|
type=\"PropertyCollector\">propertyCollector</propertyCollector><viewManager
|
||||||
|
type=\"ViewManager\">ViewManager</viewManager><about><name>VMware vCenter
|
||||||
|
Server</name><fullName>VMware vCenter Server 5.5.0 build-1750787 (Sim)</fullName><vendor>VMware,
|
||||||
|
Inc.</vendor><version>5.5.0</version><build>1750787 (Sim)</build><localeVersion>INTL</localeVersion><localeBuild>000</localeBuild><osType>linux-x64</osType><productLineId>vpx</productLineId><apiType>VirtualCenter</apiType><apiVersion>5.5</apiVersion><instanceUuid>EAB4D846-C243-426B-A021-0547644CE59D</instanceUuid><licenseProductName>VMware
|
||||||
|
VirtualCenter Server</licenseProductName><licenseProductVersion>5.0</licenseProductVersion></about><setting
|
||||||
|
type=\"OptionManager\">VpxSettings</setting><userDirectory type=\"UserDirectory\">UserDirectory</userDirectory><sessionManager
|
||||||
|
type=\"SessionManager\">SessionManager</sessionManager><authorizationManager
|
||||||
|
type=\"AuthorizationManager\">AuthorizationManager</authorizationManager><serviceManager
|
||||||
|
type=\"ServiceManager\">ServiceMgr</serviceManager><perfManager type=\"PerformanceManager\">PerfMgr</perfManager><scheduledTaskManager
|
||||||
|
type=\"ScheduledTaskManager\">ScheduledTaskManager</scheduledTaskManager><alarmManager
|
||||||
|
type=\"AlarmManager\">AlarmManager</alarmManager><eventManager type=\"EventManager\">EventManager</eventManager><taskManager
|
||||||
|
type=\"TaskManager\">TaskManager</taskManager><extensionManager type=\"ExtensionManager\">ExtensionManager</extensionManager><customizationSpecManager
|
||||||
|
type=\"CustomizationSpecManager\">CustomizationSpecManager</customizationSpecManager><customFieldsManager
|
||||||
|
type=\"CustomFieldsManager\">CustomFieldsManager</customFieldsManager><diagnosticManager
|
||||||
|
type=\"DiagnosticManager\">DiagMgr</diagnosticManager><licenseManager type=\"LicenseManager\">LicenseManager</licenseManager><searchIndex
|
||||||
|
type=\"SearchIndex\">SearchIndex</searchIndex><fileManager type=\"FileManager\">FileManager</fileManager><datastoreNamespaceManager
|
||||||
|
type=\"DatastoreNamespaceManager\">DatastoreNamespaceManager</datastoreNamespaceManager><virtualDiskManager
|
||||||
|
type=\"VirtualDiskManager\">virtualDiskManager</virtualDiskManager><snmpSystem
|
||||||
|
type=\"HostSnmpSystem\">SnmpSystem</snmpSystem><vmProvisioningChecker type=\"VirtualMachineProvisioningChecker\">ProvChecker</vmProvisioningChecker><vmCompatibilityChecker
|
||||||
|
type=\"VirtualMachineCompatibilityChecker\">CompatChecker</vmCompatibilityChecker><ovfManager
|
||||||
|
type=\"OvfManager\">OvfManager</ovfManager><ipPoolManager type=\"IpPoolManager\">IpPoolManager</ipPoolManager><dvSwitchManager
|
||||||
|
type=\"DistributedVirtualSwitchManager\">DVSManager</dvSwitchManager><hostProfileManager
|
||||||
|
type=\"HostProfileManager\">HostProfileManager</hostProfileManager><clusterProfileManager
|
||||||
|
type=\"ClusterProfileManager\">ClusterProfileManager</clusterProfileManager><complianceManager
|
||||||
|
type=\"ProfileComplianceManager\">MoComplianceManager</complianceManager><localizationManager
|
||||||
|
type=\"LocalizationManager\">LocalizationManager</localizationManager><storageResourceManager
|
||||||
|
type=\"StorageResourceManager\">StorageResourceManager</storageResourceManager><guestOperationsManager
|
||||||
|
type=\"GuestOperationsManager\">guestOperationsManager</guestOperationsManager></val></propSet></objects></returnval></RetrievePropertiesExResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
cache-control: [no-cache]
|
||||||
|
connection: [Keep-Alive]
|
||||||
|
content-length: ['3751']
|
||||||
|
content-type: [text/xml; charset=utf-8]
|
||||||
|
date: ['Wed, 23 Jul 2014 21:21:18 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?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><RetrievePropertiesEx xmlns="urn:vim25"><_this type="PropertyCollector">propertyCollector</_this><specSet><propSet><type>SessionManager</type><all>false</all><pathSet>currentSession</pathSet></propSet><objectSet><obj
|
||||||
|
type="SessionManager">SessionManager</obj><skip>false</skip></objectSet></specSet><options><maxObjects>1</maxObjects></options></RetrievePropertiesEx></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: [vmware_soap_session="52773cd3-35c6-b40a-17f1-fe664a9f08f3"; Path=/;
|
||||||
|
HttpOnly; Secure;]
|
||||||
|
SOAPAction: ['"urn:vim25/5.5"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: !!python/unicode "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<RetrievePropertiesExResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><objects><obj type=\"SessionManager\">SessionManager</obj><propSet><name>currentSession</name><val
|
||||||
|
xsi:type=\"UserSession\"><key>52773cd3-35c6-b40a-17f1-fe664a9f08f3</key><userName>my_user</userName><fullName>My User
|
||||||
|
</fullName><loginTime>2014-07-23T21:21:18.297208Z</loginTime><lastActiveTime>2014-07-23T21:21:18.297208Z</lastActiveTime><locale>en</locale><messageLocale>en</messageLocale><extensionSession>false</extensionSession><ipAddress>172.16.16.1</ipAddress><userAgent></userAgent><callCount>1</callCount></val></propSet></objects></returnval></RetrievePropertiesExResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
cache-control: [no-cache]
|
||||||
|
connection: [Keep-Alive]
|
||||||
|
content-length: ['958']
|
||||||
|
content-type: [text/xml; charset=utf-8]
|
||||||
|
date: ['Wed, 23 Jul 2014 21:21:18 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
version: 1
|
@@ -50,3 +50,18 @@ class ConnectionTests(unittest.TestCase):
|
|||||||
pwd='bad_password')
|
pwd='bad_password')
|
||||||
|
|
||||||
self.assertRaises(vim.fault.InvalidLogin, should_fail)
|
self.assertRaises(vim.fault.InvalidLogin, should_fail)
|
||||||
|
|
||||||
|
@vcr.use_cassette('smart_connection.yaml',
|
||||||
|
cassette_library_dir=fixtures_path, record_mode='none')
|
||||||
|
def test_smart_connection(self):
|
||||||
|
# see: http://python3porting.com/noconv.html
|
||||||
|
si = connect.SmartConnect(host='vcsa',
|
||||||
|
user='my_user',
|
||||||
|
pwd='my_password')
|
||||||
|
session_id = si.content.sessionManager.currentSession.key
|
||||||
|
# NOTE (hartsock): assertIsNotNone does not work in Python 2.6
|
||||||
|
self.assertTrue(session_id is not None)
|
||||||
|
self.assertEqual('52773cd3-35c6-b40a-17f1-fe664a9f08f3', session_id)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Reference in New Issue
Block a user