Merge pull request #89 from vmware/python3

Support for Python 3
This commit is contained in:
Shawn Hartsock
2014-07-28 15:06:50 -04:00
17 changed files with 602 additions and 297 deletions

View File

@@ -3,6 +3,8 @@ python:
- "2.6"
- "2.7"
- "pypy"
- "3.3"
- "3.4"
before_install:
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2; fi
@@ -10,6 +12,6 @@ before_install:
- pip install -r test-requirements.txt
install:
- python setup.py -q install
- python setup.py install
script: python setup.py test

View File

@@ -25,23 +25,19 @@ Detailed description (for [e]pydoc goes here).
"""
from six import reraise
import sys
import threading
import thread
import types
import httplib
import socket
import time
import itertools
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.VmomiSupport import nsMap, versionIdMap, versionMap, IsChildVersion
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?
"""
class closing(object):
"""
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]
if info.group(2) is not None:
port = int(info.group(2)[1:])
except ValueError, ve:
except ValueError as ve:
pass
if namespace:
@@ -256,7 +251,7 @@ def Disconnect(si):
def GetLocalTicket(si, user):
try:
sessionManager = si.content.sessionManager
except Exception, e:
except Exception as e:
if type(e).__name__ == 'ExpatError':
msg = 'Malformed response while querying for local ticket: "%s"' % e
raise vim.fault.HostConnectFault(msg=msg)
@@ -312,14 +307,17 @@ def __Login(host, port, user, pwd, service, adapter, version, path,
content = si.RetrieveContent()
except vmodl.MethodFault:
raise
except Exception, e:
except Exception as e:
# NOTE (hartsock): preserve the traceback for diagnostics
# pulling and preserving the traceback makes diagnosing connection
# failures easier since the fault will also include where inside the
# library the fault occurred. Without the traceback we have no idea
# why the connection failed beyond the message string.
(type, value, traceback) = sys.exc_info()
reraise(vim.fault.HostConnectFault(msg=str(e)), None, traceback)
if 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
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)
except vim.fault.InvalidLogin:
raise
except Exception, e:
except Exception as e:
raise
return si, stub
@@ -350,7 +348,7 @@ def __Logout(si):
if si:
content = si.RetrieveContent()
content.sessionManager.Logout()
except Exception, e:
except Exception as e:
pass
@@ -417,7 +415,7 @@ class SmartConnection(object):
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
if it exists, otherwise vimService.wsdl if it exists, otherwise None.
@@ -431,26 +429,23 @@ def __GetServiceVersionDescription(protocol, server, port, path):
@type path: string
"""
tree = ElementTree()
url = "%s://%s:%s/%s/vimServiceVersions.xml" % (protocol, server, port, path)
try:
with closing(urllib2.urlopen(url)) as sock:
if sock.getcode() == 200:
tree.parse(sock)
return tree
sock = requests.get(url, verify=False)
if sock.status_code == 200:
tree = ElementTree.fromstring(sock.content)
return tree
except ExpatError:
pass
url = "%s://%s:%s/%s/vimService.wsdl" % (protocol, server, port, path)
try:
with closing(urllib2.urlopen(url)) as sock:
if sock.getcode() == 200:
tree.parse(sock)
return tree
sock = requests.get(url, verify=False)
if sock.status_code == 200:
tree = ElementTree.fromstring(sock.content)
return tree
except ExpatError:
pass
return None
@@ -465,15 +460,15 @@ def __VersionIsSupported(desiredVersion, serviceVersionDescription):
@param desiredVersion: The version we want to see if the server supports
(eg. vim.version.version2.
@type desiredVersion: string
@param serviceVersionDescription: An ElementTree for vimServiceVersions.xml
@param serviceVersionDescription: A root ElementTree for vimServiceVersions.xml
or vimService.wsdl.
@type serviceVersionDescription: ElementTree
@type serviceVersionDescription: root ElementTree
"""
root = serviceVersionDescription.getroot()
root = serviceVersionDescription
if root.tag == 'namespaces':
# 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,' \
' which is not understood' % (root.get('version')))
desiredVersionId = versionIdMap[desiredVersion]
@@ -599,11 +594,7 @@ def OpenUrlWithBasicAuth(url, user='root', pwd=''):
the specified credentials to the server as part of the request.
Returns the response as a file-like object.
"""
pwMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
pwMgr.add_password(None, url, user, pwd)
handler = urllib2.HTTPBasicAuthHandler(pwMgr)
opener = urllib2.build_opener(handler)
return opener.open(url)
return requests.get(url, auth=HTTPBasicAuth(user, pwd), verify=False)
def OpenPathWithStub(path, stub):
"""
@@ -623,8 +614,8 @@ def OpenPathWithStub(path, stub):
raise vmodl.fault.NotSupported()
hostPort = stub.host
url = '%s://%s%s' % (protocol, hostPort, path)
request = urllib2.Request(url)
headers = {}
if stub.cookie:
request.add_header('Cookie', stub.cookie)
return urllib2.urlopen(request)
headers["Cookie"] = stub.cookie
return requests.get(url, headers=headers, verify=False)

View File

@@ -12,9 +12,10 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
# ******* 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.version2", "", "", 0, "vim25")

View File

@@ -14,6 +14,8 @@
# limitations under the License.
## Diff any two objects
from six import text_type
from six import u
from pyVmomi import VmomiSupport, types
import itertools
@@ -33,7 +35,7 @@ def IsPrimitiveType(obj):
isinstance(obj, types.short) or isinstance(obj, types.int) or
isinstance(obj, types.double) or isinstance(obj, types.float) 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.ManagedMethod) or
isinstance(obj, types.datetime) or

View File

@@ -45,7 +45,7 @@ class DynamicTypeImporter:
if self.hostSystem:
try:
dynTypeMgr = self.hostSystem.RetrieveDynamicTypeManager()
except vmodl.fault.MethodNotFound, err:
except vmodl.fault.MethodNotFound as err:
pass
if not dynTypeMgr:
@@ -139,7 +139,7 @@ class DynamicTypeConstructor:
for typeInfo in infos:
try:
fn(*typeInfo)
except Exception, err:
except Exception as err:
#Ignore errors due to duplicate importing
pass

View File

@@ -14,12 +14,14 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
# TODO (hartsocks): Introduce logging to remove the need for print function.
"""
This module is for ISO 8601 parsing
"""
__author__ = 'VMware, Inc.'
from six import iteritems
import time
from datetime import datetime, timedelta, tzinfo
import re
@@ -118,7 +120,7 @@ def ParseISO8601(datetimeStr):
if match:
try:
dt = {}
for key, defaultVal in _dtExprKeyDefValMap.iteritems():
for key, defaultVal in iteritems(_dtExprKeyDefValMap):
val = match.group(key)
if val:
if key == 'microsecond':
@@ -176,7 +178,7 @@ def ParseISO8601(datetimeStr):
datetimeVal = datetime(**dt)
if delta:
datetimeVal += delta
except Exception, e:
except Exception as e:
pass
return datetimeVal
@@ -253,7 +255,7 @@ if __name__ == '__main__':
]:
dt = ParseISO8601(testStr)
if dt == None:
print 'Failed to parse (%s)' % testStr
print('Failed to parse ({0})'.format(testStr))
assert(False)
# Make sure we can translate back
@@ -262,16 +264,16 @@ if __name__ == '__main__':
if dt.tzinfo is None:
dt = dt.replace(tzinfo=dt1.tzinfo)
if dt1 != dt:
print 'ParseISO8601 -> ISO8601Format -> ParseISO8601 failed (%s)' % testStr
print('ParseISO8601 -> ISO8601Format -> ParseISO8601 failed ({0})'.format(testStr))
assert(False)
# Make sure we can parse python isoformat()
dt2 = ParseISO8601(dt.isoformat())
if dt2 == None:
print 'ParseISO8601("%s".isoformat()) failed' % testStr
print('ParseISO8601("{0}".isoformat()) failed'.format(testStr))
assert(False)
print testStr, '->', dt, isoformat
print(testStr, '->', dt, isoformat)
# Basic form
for testStr in [
@@ -293,7 +295,7 @@ if __name__ == '__main__':
# Reject for now
dt = ParseISO8601(testStr)
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)
#print testStr, '->', dt
#assert(dt != None)
@@ -352,5 +354,5 @@ if __name__ == '__main__':
]:
dt = ParseISO8601(testStr)
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)

View File

@@ -12,9 +12,10 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
# ******* 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.version2", "vim25", "2.5", 0, "vim25")

View File

@@ -1,34 +1,46 @@
# 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");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from six import PY2
from six import PY3
from six.moves import http_client
if PY3:
long = int
basestring = str
from six import u
import sys
import os
import time
import socket
import subprocess
import thread
import urlparse
import time
from six.moves.urllib.parse import urlparse
from datetime import datetime
from xml.parsers.expat import ParserCreate
# We have our own escape functionality.
# from xml.sax.saxutils import escape
from cStringIO import StringIO
from VmomiSupport import *
from StubAdapterAccessorImpl import StubAdapterAccessorMixin
import Iso8601
if PY2:
from cStringIO import StringIO
if PY3:
from io import StringIO
from pyVmomi.VmomiSupport import *
from pyVmomi.StubAdapterAccessorImpl import StubAdapterAccessorMixin
import pyVmomi.Iso8601
import base64
from xml.parsers.expat import ExpatError
import copy
@@ -46,41 +58,41 @@ CONNECTION_POOL_IDLE_TIMEOUT_SEC = 900
NS_SEP = " "
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_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
# TODO: Change to frozendict, if available
SOAP_NSMAP = { XMLNS_SOAPENC: 'soapenc', XMLNS_SOAPENV: 'soapenv',
XMLNS_XSI: 'xsi', XMLNS_XSD: 'xsd' }
SOAP_ENVELOPE_TAG="%s:Envelope" % SOAP_NSMAP[XMLNS_SOAPENV]
SOAP_HEADER_TAG="%s:Header" % SOAP_NSMAP[XMLNS_SOAPENV]
SOAP_FAULT_TAG="%s:Fault" % SOAP_NSMAP[XMLNS_SOAPENV]
SOAP_BODY_TAG="%s:Body" % SOAP_NSMAP[XMLNS_SOAPENV]
SOAP_ENVELOPE_TAG = "{0}:Envelope".format(SOAP_NSMAP[XMLNS_SOAPENV])
SOAP_HEADER_TAG = "{0}:Header".format(SOAP_NSMAP[XMLNS_SOAPENV])
SOAP_FAULT_TAG = "{0}:Fault".format(SOAP_NSMAP[XMLNS_SOAPENV])
SOAP_BODY_TAG = "{0}:Body".format(SOAP_NSMAP[XMLNS_SOAPENV])
SOAP_ENVELOPE_START = '<%s ' % SOAP_ENVELOPE_TAG + \
' '.join(['xmlns:' + prefix + '="' + urn + '"' \
for urn, prefix in SOAP_NSMAP.iteritems()]) + \
SOAP_ENVELOPE_START = '<{0} '.format(SOAP_ENVELOPE_TAG) + \
' '.join(['xmlns:' + prefix + '="' + urn + '"' \
for urn, prefix in iteritems(SOAP_NSMAP)]) + \
'>\n'
SOAP_ENVELOPE_END = "\n</%s>" % (SOAP_ENVELOPE_TAG)
SOAP_HEADER_START="<%s>" % SOAP_HEADER_TAG
SOAP_HEADER_END="</%s>" % SOAP_HEADER_TAG
SOAP_BODY_START="<%s>" % SOAP_BODY_TAG
SOAP_BODY_END="</%s>" % SOAP_BODY_TAG
SOAP_ENVELOPE_END = "\n</{0}>".format(SOAP_ENVELOPE_TAG)
SOAP_HEADER_START = "<{0}>".format(SOAP_HEADER_TAG)
SOAP_HEADER_END = "</{0}>".format(SOAP_HEADER_TAG)
SOAP_BODY_START = "<{0}>".format(SOAP_BODY_TAG)
SOAP_BODY_END = "</{0}>".format(SOAP_BODY_TAG)
SOAP_START = SOAP_ENVELOPE_START + SOAP_BODY_START + '\n'
SOAP_END = '\n' + SOAP_BODY_END + SOAP_ENVELOPE_END
WSSE_PREFIX="wsse"
WSSE_HEADER_TAG="%s:Security" % WSSE_PREFIX
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_HEADER_START="<%s %s>" % (WSSE_HEADER_TAG, WSSE_NS)
WSSE_HEADER_END="</%s>" % WSSE_HEADER_TAG
WSSE_PREFIX = "wsse"
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 = 'xmlns:{0}="{1}"'.format(WSSE_PREFIX, WSSE_NS_URL)
WSSE_HEADER_START = "<{0} {1}>".format(WSSE_HEADER_TAG, WSSE_NS)
WSSE_HEADER_END = "</{0}>".format(WSSE_HEADER_TAG)
## MethodFault type
MethodFault = GetVmodlType("vmodl.MethodFault")
@@ -152,7 +164,7 @@ def SerializeFaultDetail(val, info=None, version=None, nsMap=None, encoding=None
if version is None:
try:
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
except AttributeError:
version = BASE_VERSION
@@ -178,7 +190,7 @@ class SoapSerializer:
self.version = version
self.nsMap = nsMap and nsMap or {}
self.encoding = encoding and encoding or XML_ENCODING
for ns, prefix in self.nsMap.iteritems():
for ns, prefix in iteritems(self.nsMap):
if prefix == '':
self.defaultNS = ns
break
@@ -194,7 +206,7 @@ class SoapSerializer:
prefix = self.nsMap.get(ns)
if not prefix:
prefix = nsPrefix
self.outermostAttrs += ' xmlns:%s="%s"' % (prefix, ns)
self.outermostAttrs += ' xmlns:{0}="{1}"'.format(prefix, ns)
self.nsMap = self.nsMap.copy()
self.nsMap[ns] = prefix
setattr(self, attrName, prefix + ":")
@@ -240,7 +252,7 @@ class SoapSerializer:
except KeyError:
# We have not seen this ns before
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
## Serialize an object (internal)
@@ -257,17 +269,17 @@ class SoapSerializer:
if info.flags & F_OPTIONAL:
return
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:
if info.type is object:
# Make sure an empty array assigned to Any is typed
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:
# Skip optional non-Any
return
else:
raise TypeError('Field "%s" is not optional' % info.name)
raise TypeError('Field "{0}" not optional'.format(info.name))
if self.outermostAttrs:
attr = self.outermostAttrs
@@ -278,7 +290,7 @@ class SoapSerializer:
# Emit default ns if tag ns is not the same
currTagNS = GetWsdlNamespace(info.version)
if currTagNS != defNS:
attr += ' xmlns="%s"' % currTagNS
attr += ' xmlns="{0}"'.format(currTagNS)
currDefNS = currTagNS
if isinstance(val, DataObject):
@@ -296,14 +308,14 @@ class SoapSerializer:
elif isinstance(val, ManagedObject):
if info.type is object:
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:
attr += ' serverGuid="%s"' % (val._serverGuid)
attr += ' serverGuid="{0}"'.format(val._serverGuid)
# val in vim type attr is not namespace qualified
# TODO: Add a new "typens" attr?
ns, name = GetQualifiedWsdlName(Type(val))
attr += ' type="%s"' % (name)
self.writer.write('<%s%s>%s</%s>' % (info.name, attr,
attr += ' type="{0}"'.format(name)
self.writer.write('<{0}{1}>{2}</{3}>'.format(info.name, attr,
val._moId.encode(self.encoding),
info.name))
elif isinstance(val, list):
@@ -326,14 +338,14 @@ class SoapSerializer:
if qName.endswith("ArrayOfManagedObject"):
qName += "Reference"
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
self.writer.write('<%s%s>' % (info.name, attr))
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
self.writer.write('<{0}{1}>'.format(info.name, attr))
itemInfo = Object(name=tag, type=itemType,
version=info.version, flags=info.flags)
for it in val:
self._Serialize(it, itemInfo, currDefNS)
self.writer.write('</%s>' % info.name)
self.writer.write('</{0}>'.format(info.name))
else:
itemType = info.type.Item
itemInfo = Object(name=info.name, type=itemType,
@@ -342,54 +354,52 @@ class SoapSerializer:
self._Serialize(it, itemInfo, defNS)
elif isinstance(val, type) or isinstance(val, type(Exception)):
if info.type is object:
attr += ' %stype="%sstring"' % (self.xsiPrefix, self.xsdPrefix)
self.writer.write('<%s%s>%s</%s>' %
(info.name, attr, GetWsdlName(val), info.name))
attr += ' {0}type="{1}string"'.format(self.xsiPrefix, self.xsdPrefix)
self.writer.write('<{0}{1}>{2}</{0}>'.format(
info.name, attr, GetWsdlName(val)))
elif isinstance(val, ManagedMethod):
if info.type is object:
attr += ' %stype="%sstring"' % (self.xsiPrefix, self.xsdPrefix)
self.writer.write('<%s%s>%s</%s>' %
(info.name, attr, val.info.wsdlName, info.name))
attr += ' {0}type="{1}string"'.format(self.xsiPrefix, self.xsdPrefix)
self.writer.write('<{0}{1}>{2}</{0}>'.format(
info.name, attr, val.info.wsdlName))
elif isinstance(val, datetime):
if info.type is object:
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)
self.writer.write('<%s%s>%s</%s>' % (info.name, attr, result,
info.name))
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr, result))
elif isinstance(val, binary):
if info.type is object:
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)
self.writer.write('<%s%s>%s</%s>' % (info.name, attr, result,
info.name))
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr, result))
elif isinstance(val, bool):
if info.type is object:
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"
self.writer.write('<%s%s>%s</%s>' % (info.name, attr, result,
info.name))
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr, result))
else:
if info.type is object:
if isinstance(val, PropertyPath):
attr += ' %stype="%sstring"' % (self.xsiPrefix, self.xsdPrefix)
attr += ' {0}type="{1}string"'.format(self.xsiPrefix, self.xsdPrefix)
else:
nsattr, qName = self._QName(Type(val), currDefNS)
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
if not isinstance(val, unicode):
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
if not isinstance(val, text_type):
# Use UTF-8 rather than self.encoding. self.encoding is for
# output of serializer, while 'val' is our input. And regardless
# 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,
# you cannot serialize it again once more. That's feature, not
# a bug.
val = str(val).decode('UTF-8')
val = str(val)
if PY2:
val = val.decode('UTF-8')
result = XmlEscape(val)
self.writer.write('<%s%s>%s</%s>' % (info.name, attr,
result.encode(self.encoding),
info.name))
self.writer.write('<{0}{1}>{2}</{0}>'.format(info.name, attr,
result.encode(self.encoding)))
## Serialize a a data object (internal)
#
@@ -406,8 +416,8 @@ class SoapSerializer:
dynType = GetCompatibleType(Type(val), self.version)
if dynType != info.type:
nsattr, qName = self._QName(dynType, currDefNS)
attr += '%s %stype="%s"' % (nsattr, self.xsiPrefix, qName)
self.writer.write('<%s%s>' % (info.name, attr))
attr += '{0} {1}type="{2}"'.format(nsattr, self.xsiPrefix, qName)
self.writer.write('<{0}{1}>'.format(info.name, attr))
if dynType is LocalizedMethodFault:
# Serialize a MethodFault as LocalizedMethodFault on wire
# See PR 670229
@@ -423,7 +433,7 @@ class SoapSerializer:
for prop in val._GetPropertyList():
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
@@ -582,7 +592,7 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
if name == "fault" and isinstance(self.stack[-1], LocalizedMethodFault):
deserializeAsLocalizedMethodFault = False
else:
raise TypeError("Invalid type for tag %s" % tag)
raise TypeError("Invalid type for tag {0}".format(tag))
xsiType = attr.get(XSI_TYPE)
if xsiType:
@@ -604,13 +614,13 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
if self.version:
objType = GetCompatibleType(objType, self.version)
if issubclass(objType, ManagedObject):
typeAttr = attr[u'type']
typeAttr = attr[u('type')]
# val in vim type attr is not namespace qualified
# However, this doesn't hurt to strip out namespace
# TODO: Get the ns from "typens" attr?
ns, name = self.GetNSAndWsdlname(typeAttr)
if u'serverGuid' in attr:
self.serverGuid = attr[u'serverGuid']
if u('serverGuid') in attr:
self.serverGuid = attr[u('serverGuid')]
self.stack.append(GuessWsdlType(name))
elif issubclass(objType, DataObject) or issubclass(objType, list):
if deserializeAsLocalizedMethodFault and issubclass(objType, Exception):
@@ -662,10 +672,10 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
elif obj is str:
try:
obj = str(data)
except UnicodeError:
except ValueError:
obj = data
elif obj is datetime:
obj = Iso8601.ParseISO8601(data)
obj = pyVmomi.Iso8601.ParseISO8601(data)
if not obj:
raise TypeError(data)
# issubclass is very expensive. Test last
@@ -772,7 +782,7 @@ class SoapResponseDeserializer(ExpatDeserializerNSHandlers):
if self.isFault and tag == "faultstring":
try:
self.msg = str(self.data)
except UnicodeError:
except ValueError:
self.msg = self.data
## Base class that implements common functionality for stub adapters.
@@ -789,7 +799,7 @@ class StubAdapterBase(StubAdapterAccessorMixin):
def ComputeVersionInfo(self, version):
versionNS = GetVersionNamespace(version)
if versionNS.find("/") >= 0:
self.versionId = '"urn:%s"' % versionNS
self.versionId = '"urn:{0}"'.format(versionNS)
else:
self.versionId = ''
self.version = version
@@ -822,33 +832,33 @@ class SoapStubAdapterBase(StubAdapterBase):
if reqContexts or samlToken:
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
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,
Object(name=key, type=str, version=self.version),
self.version,
nsMap)
result.append(ret)
if samlToken:
result.append('%s %s %s' % (WSSE_HEADER_START,
samlToken,
WSSE_HEADER_END))
result.append('{0} {1} {2}'.format(WSSE_HEADER_START,
samlToken,
WSSE_HEADER_END))
result.append(SOAP_HEADER_END)
result.append('\n')
# Serialize soap body
result.extend([SOAP_BODY_START,
'<%s xmlns="%s">' % (info.wsdlName, defaultNS),
Serialize(mo, Object(name="_this", type=ManagedObject,
version=self.version),
self.version, nsMap)])
'<{0} xmlns="{1}">'.format(info.wsdlName, defaultNS),
Serialize(mo, Object(name="_this", type=ManagedObject,
version=self.version),
self.version, nsMap)])
# Serialize soap request parameters
for (param, arg) in zip(info.params, args):
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)
## Subclass of HTTPConnection that connects over a Unix domain socket
@@ -894,9 +904,9 @@ try:
sha1.update(derCert)
sha1Digest = sha1.hexdigest().lower()
if sha1Digest != thumbprint:
raise Exception("Server has wrong SHA1 thumbprint: %s "
"(required) != %s (server)" % (
thumbprint, sha1Digest))
raise Exception("Server has wrong SHA1 thumbprint: {0} "
"(required) != {1} (server)".format(
thumbprint, sha1Digest))
# Function used to wrap sockets with SSL
_SocketWrapper = ssl.wrap_socket
@@ -1001,7 +1011,7 @@ class SSLTunnelConnection(object):
resp = tunnel.getresponse()
tunnelSocket = resp.fp
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.sock = _SocketWrapper(tunnelSocket,
keyfile=key_file, certfile=cert_file)
@@ -1139,13 +1149,13 @@ class SoapStubAdapter(SoapStubAdapterBase):
or (port, HTTPSConnectionWrapper)
if host.find(':') != -1: # is IPv6?
host = '[' + host + ']'
self.host = '%s:%d' % (host, port)
self.host = '{0}:{1}'.format(host, port)
self.path = path
if thumbprint:
self.thumbprint = thumbprint.replace(":", "").lower()
if len(self.thumbprint) != 40:
raise Exception("Invalid SHA1 thumbprint -- %s" % thumbprint)
raise Exception("Invalid SHA1 thumbprint -- {0}".format(thumbprint))
else:
self.thumbprint = None
@@ -1158,13 +1168,13 @@ class SoapStubAdapter(SoapStubAdapterBase):
if url:
self.path = url
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.
self.host = "%s:%d" % (httpProxyHost, httpProxyPort)
self.host = "{0}:{1}".format(httpProxyHost, httpProxyPort)
self.poolSize = poolSize
self.pool = []
self.connectionPoolTimeout = connectionPoolTimeout
self.lock = thread.allocate_lock()
self.lock = threading.Lock()
self.schemeArgs = {}
if certKeyFile:
self.schemeArgs['key_file'] = certKeyFile
@@ -1207,7 +1217,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
headers = {'Cookie' : self.cookie,
'SOAPAction' : self.versionId,
'Content-Type' : 'text/xml; charset=%s' % XML_ENCODING}
'Content-Type': 'text/xml; charset={0}'.format(XML_ENCODING)}
if self._acceptCompressedResponses:
headers['Accept-Encoding'] = 'gzip, deflate'
req = self.SerializeRequest(mo, info, args)
@@ -1251,7 +1261,7 @@ class SoapStubAdapter(SoapStubAdapterBase):
raise obj # pylint: disable-msg=E0702
else:
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
# SoapStubAdapter lock must be acquired before this method is called.
@@ -1384,14 +1394,14 @@ class SoapCmdStubAdapter(SoapStubAdapterBase):
(outText, errText) = p.communicate(req)
if p.returncode < 0:
# 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)
try:
(responseHeaders, responseBody) = ParseHttpResponse(outText)
obj = SoapResponseDeserializer(self).Deserialize(responseBody, info.result)
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)
if p.returncode == 0:
@@ -1491,7 +1501,7 @@ class SessionOrientedStub(StubAdapterBase):
raise obj
# Raise any socket/httplib errors caught above.
raise
raise SystemError()
## Retrieve a managed property
#
@@ -1513,7 +1523,7 @@ class SessionOrientedStub(StubAdapterBase):
time.sleep(self.retryDelay)
retriesLeft -= 1
continue
except Exception, e:
except Exception as e:
if isinstance(e, self.SESSION_EXCEPTIONS):
# Our session might've timed out, change our state and retry.
self._SetStateUnauthenticated()
@@ -1521,7 +1531,7 @@ class SessionOrientedStub(StubAdapterBase):
raise e
return obj
# Raise any socket/httplib errors caught above.
raise
raise SystemError()
## Handle the login method call
#

View File

@@ -12,8 +12,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from VmomiSupport import GetVmodlType
from __future__ import absolute_import
from pyVmomi.VmomiSupport import GetVmodlType
class StubAdapterAccessorMixin:
def __init__(self):

View File

@@ -12,8 +12,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from VmomiSupport import nsMap, versionMap, versionIdMap, serviceNsMap, parentMap
from __future__ import absolute_import
from pyVmomi.VmomiSupport import nsMap, versionMap, versionIdMap, serviceNsMap, parentMap
## Add an API version
def AddVersion(version, ns, versionId='', isLegacy=0, serviceNs=''):

View File

@@ -14,21 +14,34 @@
# limitations under the License.
## VMOMI support code
from __future__ import absolute_import
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
import Iso8601
import pyVmomi.Iso8601
import base64
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)
try:
from pyVmomiSettings import allowGetSet
from pyVmomi.pyVmomiSettings import allowGetSet
_allowGetSet = allowGetSet
except:
_allowGetSet = True
try:
from pyVmomiSettings import allowCapitalizedNames
from pyVmomi.pyVmomiSettings import allowCapitalizedNames
_allowCapitalizedNames = allowCapitalizedNames
except:
_allowCapitalizedNames = True
@@ -176,13 +189,13 @@ class LazyObject(Object):
else:
raise AttributeError(attr)
class Link(unicode):
class Link(text_type):
def __new__(cls, obj):
if isinstance(obj, basestring):
return unicode.__new__(cls, obj)
return text_type.__new__(cls, obj)
elif isinstance(obj, DataObject):
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")
else:
raise ValueError
@@ -348,7 +361,7 @@ class ManagedObject(object):
args = list(posargs) + [None] * (len(info.params) - len(posargs))
if len(kwargs) > 0:
paramNames = [param.name for param in info.params]
for (k, v) in kwargs.items():
for (k, v) in list(kwargs.items()):
try:
idx = paramNames.index(k)
except ValueError:
@@ -1026,7 +1039,7 @@ def GetWsdlTypes():
with _lazyLock:
for ns, name in _wsdlDefMap:
GetWsdlType(ns, name)
return _wsdlTypeMap.itervalues()
return itervalues(_wsdlTypeMap)
## Get the qualified XML schema name (ns, name) of a 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
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 = {}
for v in versions.iterkeys():
mappings[v] = set(parent for parent in parentMap[v].iterkeys()
if parent != v and versions.has_key(parent))
for v in iterkeys(versions):
mappings[v] = set(parent for parent in iterkeys(parentMap[v])
if parent != v and parent in versions.keys())
res = []
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:
return res
el.sort()
for k in el:
res.insert(0, k)
del mappings[k]
for values in mappings.itervalues():
for values in itervalues(mappings):
values.discard(k)
@@ -1218,7 +1231,7 @@ def GetCompatibleType(type, version):
## Invert an injective mapping
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()
nsMap = {}
@@ -1227,7 +1240,7 @@ versionMap = {}
serviceNsMap = { BASE_VERSION : XMLNS_VMODL_BASE.split(":")[-1] }
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
bool = type("bool", (int,),
@@ -1237,7 +1250,7 @@ short = type("short", (int,), {})
double = type("double", (float,), {})
URI = type("URI", (str,), {})
binary = type("binary", (str,), {})
PropertyPath = type("PropertyPath", (unicode,), {})
PropertyPath = type("PropertyPath", (text_type,), {})
# _wsdlTypeMapNSs store namespaces added to _wsdlTypeMap in _SetWsdlType
_wsdlTypeMapNSs = set()
@@ -1263,7 +1276,7 @@ _wsdlTypeMap = {
}
_wsdlNameMap = InverseMap(_wsdlTypeMap)
for ((ns, name), typ) in _wsdlTypeMap.items():
for ((ns, name), typ) in iteritems(dict(_wsdlTypeMap)):
if typ is not NoneType:
setattr(types, typ.__name__, typ)
_wsdlTypeMapNSs.add(ns)
@@ -1277,8 +1290,8 @@ del name, typ
# unicode is mapped to wsdl name 'string' (Cannot put in wsdlTypeMap or name
# collision with non-unicode string)
_wsdlNameMap[unicode] = (XMLNS_XSD, 'string')
_wsdlNameMap[CreateArrayType(unicode)] = (XMLNS_VMODL_BASE, 'ArrayOfString')
_wsdlNameMap[text_type] = (XMLNS_XSD, 'string')
_wsdlNameMap[CreateArrayType(text_type)] = (XMLNS_VMODL_BASE, 'ArrayOfString')
# _wsdlMethodNSs store namespaces added to _wsdlMethodMap in _SetWsdlMethod
_wsdlMethodNSs = set()
@@ -1322,7 +1335,7 @@ vmodlTypes = {
vmodlNames = {}
## 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:
try:
arrayType = typ.Array
@@ -1454,7 +1467,7 @@ class StringDict(dict):
# Same as dict setdefault, except this will call through our __setitem__
def update(self, *args, **kwargs):
for k, v in dict(*args, **kwargs).iteritems():
for k, v in iteritems(dict(*args, **kwargs)):
self[k] = v
# Same as dict setdefault, except this will call through our __setitem__

View File

@@ -12,7 +12,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
# In VmomiSupport, to support dynamic type loading, all the data types are
# 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
@@ -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.exit(1)
import VmomiSupport
import CoreTypes
import pyVmomi.VmomiSupport
import pyVmomi.CoreTypes
try:
import ReflectTypes
except ImportError:
pass
try:
import ServerObjects
import pyVmomi.ServerObjects
except ImportError:
pass
try:
import InternalServerObjects
import pyVmomi.InternalServerObjects
except ImportError:
pass
# Import all the known product-specific types
# XXX: Make this search the package for types?
try:
import DrObjects
import pyVmomi.DrObjects
except ImportError:
pass
try:
import DrextObjects
import pyVmomi.DrextObjects
except ImportError:
pass
try:
import HbrReplicaTypes
import pyVmomi.HbrReplicaTypes
except ImportError:
pass
try:
import HmsObjects
import pyVmomi.HmsObjects
except ImportError:
pass
try:
import HostdObjects
import pyVmomi.HostdObjects
except ImportError:
pass
try:
import VpxObjects
import pyVmomi.VpxObjects
except ImportError:
pass
try:
import VorbTypes
import pyVmomi.VorbTypes
except ImportError:
pass
try:
import DodoTypes
import pyVmomi.DodoTypes
except ImportError:
pass
try:
import VmwauthproxyTypes
import pyVmomi.VmwauthproxyTypes
except ImportError:
pass
try:
import DmsTypes
import pyVmomi.DmsTypes
except ImportError:
pass
try:
import OmsTypes
import pyVmomi.OmsTypes
except ImportError:
pass
try:
import HmoTypes
import pyVmomi.HmoTypes
except ImportError:
pass
try:
import CimsfccTypes
import pyVmomi.CimsfccTypes
except ImportError:
pass
try:
import TaskupdaterTypes
import pyVmomi.TaskupdaterTypes
except ImportError:
pass
try:
import ImgFactTypes
import pyVmomi.ImgFactTypes
except ImportError:
pass
try:
import VpxapiTypes
import pyVmomi.VpxapiTypes
except ImportError:
pass
try:
import CsiObjects
import pyVmomi.CsiObjects
except ImportError:
pass
try:
import HostdTypes
import pyVmomi.HostdTypes
except ImportError:
pass
try:
import TaggingObjects
import pyVmomi.TaggingObjects
except ImportError:
pass
try:
import NfcTypes
import pyVmomi.NfcTypes
except ImportError:
pass
try:
import SmsObjects
import pyVmomi.SmsObjects
except ImportError:
pass
try:
import SpsObjects
import pyVmomi.SpsObjects
except ImportError:
pass
try:
import DataserviceObjects
import pyVmomi.DataserviceObjects
except ImportError:
pass
# Start of update manager specific types
try:
import IntegrityObjects
import pyVmomi.IntegrityObjects
except ImportError:
pass
try:
import SysimageObjects
import pyVmomi.SysimageObjects
except ImportError:
pass
# End of update manager specific types
try:
import RbdTypes
import pyVmomi.RbdTypes
except ImportError:
pass
# Import Profile based management specific VMODL
try:
import PbmObjects
import pyVmomi.PbmObjects
except ImportError:
pass
try:
import CisLicenseTypes
import pyVmomi.CisLicenseTypes
except ImportError:
pass
try:
import TestTypes
import pyVmomi.TestTypes
except ImportError:
pass
try:
import SsoTypes
import pyVmomi.SsoTypes
except ImportError:
pass
try:
import CisCmTypes
import pyVmomi.CisCmTypes
except ImportError:
pass
try:
import DataserviceTypes
import pyVmomi.DataserviceTypes
except ImportError:
pass
@@ -194,18 +194,18 @@ except ImportError:
# As well load it proactively.
# Note: This should be done before importing SoapAdapter as it uses
# 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
types = VmomiSupport.types
types = pyVmomi.VmomiSupport.types
# This will allow files to use Create** functions
# directly from pyVmomi
CreateEnumType = VmomiSupport.CreateEnumType
CreateDataType = VmomiSupport.CreateDataType
CreateManagedType = VmomiSupport.CreateManagedType
CreateEnumType = pyVmomi.VmomiSupport.CreateEnumType
CreateDataType = pyVmomi.VmomiSupport.CreateDataType
CreateManagedType = pyVmomi.VmomiSupport.CreateManagedType
# For all the top level names, creating a LazyModule object
# in the global namespace of pyVmomi. Files can just import the
@@ -214,14 +214,14 @@ CreateManagedType = VmomiSupport.CreateManagedType
# ALLOWED: from pyVmomi import vim
# NOT ALLOWED: from pyVmomi import vim.host
_globals = globals()
for name in VmomiSupport._topLevelNames:
upperCaseName = VmomiSupport.Capitalize(name)
obj = VmomiSupport.LazyModule(name)
for name in pyVmomi.VmomiSupport._topLevelNames:
upperCaseName = pyVmomi.VmomiSupport.Capitalize(name)
obj = pyVmomi.VmomiSupport.LazyModule(name)
_globals[name] = obj
if VmomiSupport._allowCapitalizedNames:
if pyVmomi.VmomiSupport._allowCapitalizedNames:
_globals[upperCaseName] = obj
if not hasattr(VmomiSupport.types, name):
setattr(VmomiSupport.types, name, obj)
if VmomiSupport._allowCapitalizedNames:
setattr(VmomiSupport.types, upperCaseName, obj)
if not hasattr(pyVmomi.VmomiSupport.types, name):
setattr(pyVmomi.VmomiSupport.types, name, obj)
if pyVmomi.VmomiSupport._allowCapitalizedNames:
setattr(pyVmomi.VmomiSupport.types, upperCaseName, obj)
del _globals

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python
# 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");
# 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
"""
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 pyVmomi import vmodl
import argparse
import atexit
import getpass
import sys
def GetArgs():
"""
Supports the command-line arguments listed below.
"""
parser = argparse.ArgumentParser(description='Process args for retrieving all the Virtual Machines')
parser.add_argument('-s', '--host', required=True, action='store', help='Remote host to connect to')
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')
parser = argparse.ArgumentParser(
description='Process args for retrieving all the Virtual Machines')
parser.add_argument('-s', '--host', required=True, action='store',
help='Remote host to connect to')
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()
return args
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
# 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 depth > maxdepth:
return
@@ -57,23 +69,20 @@ def PrintVmInfo(vm, depth=1):
return
summary = vm.summary
print "Name : ", summary.config.name
print "Path : ", summary.config.vmPathName
print "Guest : ", summary.config.guestFullName
print "Instance UUID : ", vm.summary.config.instanceUuid
print "BIOS UUID : ", vm.summary.config.uuid
print("Name : ", summary.config.name)
print("Path : ", summary.config.vmPathName)
print("Guest : ", summary.config.guestFullName)
annotation = summary.config.annotation
if annotation != None and annotation != "":
print "Annotation : ", annotation
print "State : ", summary.runtime.powerState
print("Annotation : ", annotation)
print("State : ", summary.runtime.powerState)
if summary.guest != None:
ip = summary.guest.ipAddress
if ip != None and ip != "":
print "IP : ", ip
print("IP : ", ip)
if summary.runtime.question != None:
print "Question : ", summary.runtime.question.text
print ""
print("Question : ", summary.runtime.question.text)
print("")
def main():
"""
@@ -84,36 +93,28 @@ def main():
if args.password:
password = args.password
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,
user=args.user,
pwd=password,
port=int(args.port))
except IOError, e:
pass
if not si:
print "Could not connect to the specified host using specified username and password"
return -1
si = SmartConnect(host=args.host,
user=args.user,
pwd=password,
port=int(args.port))
if not si:
print("Could not connect to the specified host using specified "
"username and password")
return -1
atexit.register(Disconnect, si)
content = si.RetrieveContent()
datacenter = content.rootFolder.childEntity[0]
vmFolder = datacenter.vmFolder
vmList = vmFolder.childEntity
for vm in vmList:
PrintVmInfo(vm)
except vmodl.MethodFault, e:
print "Caught vmodl fault : " + e.msg
return -1
except Exception, e:
print "Caught exception : " + str(e)
return -1
atexit.register(Disconnect, si)
content = si.RetrieveContent()
for child in content.rootFolder.childEntity:
if hasattr(child, 'vmFolder'):
datacenter = child
vmFolder = datacenter.vmFolder
vmList = vmFolder.childEntity
for vm in vmList:
PrintVmInfo(vm)
return 0
# Start program

View File

@@ -19,6 +19,8 @@
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 pyVmomi import vim, vmodl
@@ -107,7 +109,7 @@ def main():
try:
vmnames = args.vmname
if not len(vmnames):
print "No virtual machine specified for poweron"
print("No virtual machine specified for poweron")
sys.exit()
si = None
@@ -116,10 +118,10 @@ def main():
user=args.user,
pwd=password,
port=int(args.port))
except IOError, e:
except IOError:
pass
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()
atexit.register(Disconnect, si)
@@ -139,11 +141,11 @@ def main():
# Wait for power on to complete
WaitForTasks(tasks, si)
print "Virtual Machine(s) have been powered on successfully"
except vmodl.MethodFault, e:
print "Caught vmodl fault : " + e.msg
except Exception, e:
print "Caught Exception : " + str(e)
print("Virtual Machine(s) have been powered on successfully")
except vmodl.MethodFault as e:
print("Caught vmodl fault : " + e.msg)
except Exception as e:
print("Caught Exception : " + str(e))
# Start program
if __name__ == "__main__":

View File

@@ -1,4 +1,4 @@
mock
contextdecorator
PyYAML>=3.11
testtools>=0.9.34
vcrpy>=1.0.2
vcrpy

265
tests/fixtures/smart_connection.yaml vendored Normal file
View 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

View File

@@ -50,3 +50,18 @@ class ConnectionTests(unittest.TestCase):
pwd='bad_password')
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()