Initial source drop
This is the initial version of pyVmomi which represents vSphere API 5.1. Going forward, expect only the 'Objects' and 'Types' generated source files to need updating via official OSS drops.
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.pyc
|
||||
build
|
||||
dist
|
||||
2
MANIFEST.in
Normal file
2
MANIFEST.in
Normal file
@@ -0,0 +1,2 @@
|
||||
include README.md
|
||||
recursive-include sample *
|
||||
18
README.md
18
README.md
@@ -1,2 +1,16 @@
|
||||
pyvomomi
|
||||
========
|
||||
pyVmomi is a Python SDK for the VMware vSphere API that allows you to
|
||||
manipulate ESX, ESXi, and vCenter using scripts.
|
||||
|
||||
To get started, check out the examples in `sample/poweronvm.py` and
|
||||
`sample/getallvms.py`.
|
||||
|
||||
You can install this as a package. Just run `python setup.py bdist_egg`
|
||||
and then use `pip` or `easy_install` to deploy it on your system.
|
||||
|
||||
There are other bindings of this API in other languages. See:
|
||||
|
||||
* **vijava** (Java): http://vijava.sourceforge.net/
|
||||
* **rbvmomi** (Ruby): https://github.com/vmware/rbvmomi
|
||||
* **vSphere SDK for Perl** (non-free): https://my.vmware.com/group/vmware/details?downloadGroup=VSP510-SDKPERL-510&productId=285
|
||||
|
||||
Have fun!
|
||||
|
||||
12
pyVim/__init__.py
Normal file
12
pyVim/__init__.py
Normal file
@@ -0,0 +1,12 @@
|
||||
## @file pyVim/__init__.py
|
||||
## @brief A client-side Python API that wraps pyVmomi.
|
||||
##
|
||||
##
|
||||
|
||||
##
|
||||
## @mainpage
|
||||
##
|
||||
## A client-side Python API that wraps pyVmomi.
|
||||
##
|
||||
##
|
||||
|
||||
626
pyVim/connect.py
Normal file
626
pyVim/connect.py
Normal file
@@ -0,0 +1,626 @@
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
## @file connect.py
|
||||
## @brief Connect to a VMOMI ServiceInstance.
|
||||
##
|
||||
## Detailed description (for Doxygen goes here)
|
||||
|
||||
"""
|
||||
Connect to a VMOMI ServiceInstance.
|
||||
|
||||
Detailed description (for [e]pydoc goes here).
|
||||
"""
|
||||
|
||||
import sys
|
||||
import threading
|
||||
import thread
|
||||
import types
|
||||
import httplib
|
||||
import socket
|
||||
import time
|
||||
import itertools
|
||||
import re
|
||||
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 urllib
|
||||
|
||||
|
||||
"""
|
||||
Global regular expression for parsing host and port connection
|
||||
See http://www.ietf.org/rfc/rfc3986.txt sec 3.2.2
|
||||
"""
|
||||
_rx = re.compile(r"(^\[.+\]|[^:]+)(:\d+)?$")
|
||||
|
||||
_si = None
|
||||
"""
|
||||
Global (thread-shared) ServiceInstance
|
||||
|
||||
@todo: Get rid of me?
|
||||
"""
|
||||
|
||||
|
||||
class closing(object):
|
||||
"""
|
||||
Helper class for using closable objects in a 'with' statement,
|
||||
similar to the one provided by contextlib.
|
||||
"""
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
def __enter__(self):
|
||||
return self.obj
|
||||
def __exit__(self, *exc_info):
|
||||
self.obj.close()
|
||||
|
||||
|
||||
class VimSessionOrientedStub(SessionOrientedStub):
|
||||
'''A vim-specific SessionOrientedStub. See the SessionOrientedStub class
|
||||
in pyVmomi/SoapAdapter.py for more information.'''
|
||||
|
||||
# The set of exceptions that should trigger a relogin by the session stub.
|
||||
SESSION_EXCEPTIONS = (
|
||||
vim.fault.NotAuthenticated,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def makeUserLoginMethod(username, password, locale=None):
|
||||
'''Return a function that will call the vim.SessionManager.Login() method
|
||||
with the given parameters. The result of this function can be passed as
|
||||
the "loginMethod" to a SessionOrientedStub constructor.'''
|
||||
def _doLogin(soapStub):
|
||||
si = vim.ServiceInstance("ServiceInstance", soapStub)
|
||||
sm = si.content.sessionManager
|
||||
if not sm.currentSession:
|
||||
si.content.sessionManager.Login(username, password, locale)
|
||||
|
||||
return _doLogin
|
||||
|
||||
@staticmethod
|
||||
def makeExtensionLoginMethod(extensionKey):
|
||||
'''Return a function that will call the vim.SessionManager.Login() method
|
||||
with the given parameters. The result of this function can be passed as
|
||||
the "loginMethod" to a SessionOrientedStub constructor.'''
|
||||
def _doLogin(soapStub):
|
||||
si = vim.ServiceInstance("ServiceInstance", soapStub)
|
||||
sm = si.content.sessionManager
|
||||
if not sm.currentSession:
|
||||
si.content.sessionManager.LoginExtensionByCertificate(extensionKey)
|
||||
|
||||
return _doLogin
|
||||
|
||||
@staticmethod
|
||||
def makeCertHokTokenLoginMethod(stsUrl, stsCert=None):
|
||||
'''Return a function that will call the vim.SessionManager.LoginByToken()
|
||||
after obtaining a HoK SAML token from the STS. The result of this function
|
||||
can be passed as the "loginMethod" to a SessionOrientedStub constructor.
|
||||
|
||||
@param stsUrl: URL of the SAML Token issuing service. (i.e. SSO server).
|
||||
@param stsCert: public key of the STS service.
|
||||
'''
|
||||
assert(stsUrl)
|
||||
|
||||
def _doLogin(soapStub):
|
||||
import sso
|
||||
cert = soapStub.schemeArgs['cert_file']
|
||||
key = soapStub.schemeArgs['key_file']
|
||||
authenticator = sso.SsoAuthenticator(sts_url=stsUrl,
|
||||
sts_cert=stsCert)
|
||||
|
||||
samlAssertion = authenticator.get_hok_saml_assertion(cert,key)
|
||||
|
||||
|
||||
def _requestModifier(request):
|
||||
return sso.add_saml_context(request, samlAssertion, key)
|
||||
|
||||
si = vim.ServiceInstance("ServiceInstance", soapStub)
|
||||
sm = si.content.sessionManager
|
||||
if not sm.currentSession:
|
||||
with soapStub.requestModifier(_requestModifier):
|
||||
try:
|
||||
soapStub.samlToken = samlAssertion
|
||||
si.content.sessionManager.LoginByToken()
|
||||
finally:
|
||||
soapStub.samlToken = None
|
||||
|
||||
return _doLogin
|
||||
|
||||
@staticmethod
|
||||
def makeCredBearerTokenLoginMethod(username,
|
||||
password,
|
||||
stsUrl,
|
||||
stsCert=None):
|
||||
'''Return a function that will call the vim.SessionManager.LoginByToken()
|
||||
after obtaining a Bearer token from the STS. The result of this function
|
||||
can be passed as the "loginMethod" to a SessionOrientedStub constructor.
|
||||
|
||||
@param username: username of the user/service registered with STS.
|
||||
@param password: password of the user/service registered with STS.
|
||||
@param stsUrl: URL of the SAML Token issueing service. (i.e. SSO server).
|
||||
@param stsCert: public key of the STS service.
|
||||
'''
|
||||
assert(username)
|
||||
assert(password)
|
||||
assert(stsUrl)
|
||||
|
||||
def _doLogin(soapStub):
|
||||
import sso
|
||||
cert = soapStub.schemeArgs['cert_file']
|
||||
key = soapStub.schemeArgs['key_file']
|
||||
authenticator = sso.SsoAuthenticator(sts_url=stsUrl,
|
||||
sts_cert=stsCert)
|
||||
samlAssertion = authenticator.get_bearer_saml_assertion(username,
|
||||
password,
|
||||
cert,
|
||||
key)
|
||||
si = vim.ServiceInstance("ServiceInstance", soapStub)
|
||||
sm = si.content.sessionManager
|
||||
if not sm.currentSession:
|
||||
try:
|
||||
soapStub.samlToken = samlAssertion
|
||||
si.content.sessionManager.LoginByToken()
|
||||
finally:
|
||||
soapStub.samlToken = None
|
||||
|
||||
return _doLogin
|
||||
|
||||
|
||||
def Connect(host='localhost', port=443, user='root', pwd='',
|
||||
service="hostd", adapter="SOAP", namespace=None, path="/sdk",
|
||||
version=None, keyFile=None, certFile=None):
|
||||
"""
|
||||
Connect to the specified server, login and return the service
|
||||
instance object.
|
||||
|
||||
Throws any exception back to caller. The service instance object is
|
||||
also saved in the library for easy access.
|
||||
|
||||
Clients should modify the service parameter only when connecting to
|
||||
a VMOMI server other than hostd/vpxd. For both of the latter, the
|
||||
default value is fine.
|
||||
|
||||
@param host: Which host to connect to.
|
||||
@type host: string
|
||||
@param port: Port
|
||||
@type port: int
|
||||
@param user: User
|
||||
@type user: string
|
||||
@param pwd: Password
|
||||
@type pwd: string
|
||||
@param service: Service
|
||||
@type service: string
|
||||
@param adapter: Adapter
|
||||
@type adapter: string
|
||||
@param namespace: Namespace *** Deprecated: Use version instead ***
|
||||
@type namespace: string
|
||||
@param path: Path
|
||||
@type path: string
|
||||
@param version: Version
|
||||
@type version: string
|
||||
@param keyFile: ssl key file path
|
||||
@type keyFile: string
|
||||
@param certFile: ssl cert file path
|
||||
@type certFile: string
|
||||
"""
|
||||
try:
|
||||
info = re.match(_rx, host)
|
||||
if info is not None:
|
||||
host = info.group(1)
|
||||
if host[0] == '[':
|
||||
host = info.group(1)[1:-1]
|
||||
if info.group(2) is not None:
|
||||
port = int(info.group(2)[1:])
|
||||
except ValueError, ve:
|
||||
pass
|
||||
|
||||
if namespace:
|
||||
assert(version is None)
|
||||
version = versionMap[namespace]
|
||||
elif not version:
|
||||
version="vim.version.version6"
|
||||
si, stub = __Login(host, port, user, pwd, service, adapter, version, path,
|
||||
keyFile, certFile)
|
||||
SetSi(si)
|
||||
|
||||
return si
|
||||
|
||||
|
||||
def Disconnect(si):
|
||||
"""
|
||||
Disconnect (logout) service instance
|
||||
@param si: Service instance (returned from Connect)
|
||||
"""
|
||||
# Logout
|
||||
__Logout(si)
|
||||
SetSi(None)
|
||||
|
||||
|
||||
## Method that gets a local ticket for the specified user
|
||||
def GetLocalTicket(si, user):
|
||||
try:
|
||||
sessionManager = si.content.sessionManager
|
||||
except Exception, e:
|
||||
if type(e).__name__ == 'ExpatError':
|
||||
msg = 'Malformed response while querying for local ticket: "%s"' % e
|
||||
raise vim.fault.HostConnectFault(msg=msg)
|
||||
else:
|
||||
msg = 'Failed to query for local ticket: "%s"' % e
|
||||
raise vim.fault.HostConnectFault(msg=msg)
|
||||
localTicket = sessionManager.AcquireLocalTicket(userName=user)
|
||||
return (localTicket.userName, file(localTicket.passwordFilePath).read())
|
||||
|
||||
|
||||
## Private method that performs the actual Connect and returns a
|
||||
## connected service instance object.
|
||||
|
||||
def __Login(host, port, user, pwd, service, adapter, version, path,
|
||||
keyFile, certFile):
|
||||
"""
|
||||
Private method that performs the actual Connect and returns a
|
||||
connected service instance object.
|
||||
|
||||
@param host: Which host to connect to.
|
||||
@type host: string
|
||||
@param port: Port
|
||||
@type port: int
|
||||
@param user: User
|
||||
@type user: string
|
||||
@param pwd: Password
|
||||
@type pwd: string
|
||||
@param service: Service
|
||||
@type service: string
|
||||
@param adapter: Adapter
|
||||
@type adapter: string
|
||||
@param version: Version
|
||||
@type version: string
|
||||
@param path: Path
|
||||
@type path: string
|
||||
@param keyFile: ssl key file path
|
||||
@type keyFile: string
|
||||
@param certFile: ssl cert file path
|
||||
@type certFile: string
|
||||
"""
|
||||
|
||||
# XXX remove the adapter and service arguments once dependent code is fixed
|
||||
if adapter != "SOAP":
|
||||
raise ValueError(adapter)
|
||||
|
||||
# Create the SOAP stub adapter
|
||||
stub = SoapStubAdapter(host, port, version=version, path=path,
|
||||
certKeyFile=keyFile, certFile=certFile)
|
||||
|
||||
# Get Service instance
|
||||
si = vim.ServiceInstance("ServiceInstance", stub)
|
||||
try:
|
||||
content = si.RetrieveContent()
|
||||
except vmodl.MethodFault:
|
||||
raise
|
||||
except Exception, e:
|
||||
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:
|
||||
try:
|
||||
(user, pwd) = GetLocalTicket(si, user)
|
||||
except:
|
||||
pass # This is not supported against vCenter, and connecting
|
||||
# with an empty password is fine in debug builds
|
||||
|
||||
# Login
|
||||
try:
|
||||
x = content.sessionManager.Login(user, pwd, None)
|
||||
except vim.fault.InvalidLogin:
|
||||
raise
|
||||
except Exception, e:
|
||||
raise
|
||||
return si, stub
|
||||
|
||||
|
||||
## Private method that performs the actual Disonnect
|
||||
|
||||
def __Logout(si):
|
||||
"""
|
||||
Disconnect (logout) service instance
|
||||
@param si: Service instance (returned from Connect)
|
||||
"""
|
||||
try:
|
||||
if si:
|
||||
content = si.RetrieveContent()
|
||||
content.sessionManager.Logout()
|
||||
except Exception, e:
|
||||
pass
|
||||
|
||||
|
||||
## Get the saved service instance.
|
||||
|
||||
def GetSi():
|
||||
""" Get the saved service instance. """
|
||||
return _si
|
||||
|
||||
|
||||
## Set the saved service instance.
|
||||
|
||||
def SetSi(si):
|
||||
""" Set the saved service instance. """
|
||||
|
||||
global _si
|
||||
_si = si
|
||||
|
||||
|
||||
## Get the global saved stub
|
||||
|
||||
def GetStub():
|
||||
""" Get the global saved stub. """
|
||||
si = GetSi()
|
||||
if si:
|
||||
return si._GetStub()
|
||||
return None;
|
||||
|
||||
## RAII-style class for managing connections
|
||||
|
||||
class Connection(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.si = None
|
||||
|
||||
def __enter__(self):
|
||||
self.si = Connect(*self.args, **self.kwargs)
|
||||
return self.si
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
if self.si:
|
||||
Disconnect(self.si)
|
||||
self.si = None
|
||||
|
||||
class SmartConnection(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.si = None
|
||||
|
||||
def __enter__(self):
|
||||
self.si = SmartConnect(*self.args, **self.kwargs)
|
||||
return self.si
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
if self.si:
|
||||
Disconnect(self.si)
|
||||
self.si = None
|
||||
|
||||
## Private method that returns 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.
|
||||
|
||||
def __GetServiceVersionDescription(protocol, server, port, path):
|
||||
"""
|
||||
Private method that returns 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.
|
||||
|
||||
@param protocol: What protocol to use for the connection (e.g. https or http).
|
||||
@type protocol: string
|
||||
@param server: Which server to connect to.
|
||||
@type server: string
|
||||
@param port: Port
|
||||
@type port: int
|
||||
@param path: Path
|
||||
@type path: string
|
||||
"""
|
||||
|
||||
tree = ElementTree()
|
||||
|
||||
url = "%s://%s:%s/%s/vimServiceVersions.xml" % (protocol, server, port, path)
|
||||
try:
|
||||
with closing(urllib.urlopen(url)) as sock:
|
||||
if sock.getcode() == 200:
|
||||
tree.parse(sock)
|
||||
return tree
|
||||
except ExpatError:
|
||||
pass
|
||||
|
||||
url = "%s://%s:%s/%s/vimService.wsdl" % (protocol, server, port, path)
|
||||
try:
|
||||
with closing(urllib.urlopen(url)) as sock:
|
||||
if sock.getcode() == 200:
|
||||
tree.parse(sock)
|
||||
return tree
|
||||
except ExpatError:
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
## Private method that returns true if the service version description document
|
||||
## indicates that the desired version is supported
|
||||
|
||||
def __VersionIsSupported(desiredVersion, serviceVersionDescription):
|
||||
"""
|
||||
Private method that returns true if the service version description document
|
||||
indicates that the desired version is supported
|
||||
|
||||
@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
|
||||
or vimService.wsdl.
|
||||
@type serviceVersionDescription: ElementTree
|
||||
"""
|
||||
|
||||
root = serviceVersionDescription.getroot()
|
||||
if root.tag == 'namespaces':
|
||||
# serviceVersionDescription appears to be a vimServiceVersions.xml document
|
||||
if root.get('version') <> '1.0':
|
||||
raise RuntimeError('vimServiceVersions.xml has version %s,' \
|
||||
' which is not understood' % (root.get('version')))
|
||||
desiredVersionId = versionIdMap[desiredVersion]
|
||||
supportedVersion = None
|
||||
for namespace in root.findall('namespace'):
|
||||
versionId = namespace.findtext('version')
|
||||
if versionId == desiredVersionId:
|
||||
return True
|
||||
else:
|
||||
for versionId in namespace.findall('priorVersions/version'):
|
||||
if versionId.text == desiredVersionId:
|
||||
return True
|
||||
else:
|
||||
# serviceVersionDescription must be a vimService.wsdl document
|
||||
wsdlNS = 'http://schemas.xmlsoap.org/wsdl/'
|
||||
importElement = serviceVersionDescription.find('.//{%s}import' % wsdlNS)
|
||||
supportedVersion = versionMap[importElement.get('namespace')[4:]]
|
||||
if IsChildVersion(supportedVersion, desiredVersion):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
## Private method that returns the most preferred API version supported by the
|
||||
## specified server,
|
||||
|
||||
def __FindSupportedVersion(protocol, server, port, path, preferredApiVersions):
|
||||
"""
|
||||
Private method that returns the most preferred API version supported by the
|
||||
specified server,
|
||||
|
||||
@param protocol: What protocol to use for the connection (e.g. https or http).
|
||||
@type protocol: string
|
||||
@param server: Which server to connect to.
|
||||
@type server: string
|
||||
@param port: Port
|
||||
@type port: int
|
||||
@param path: Path
|
||||
@type path: string
|
||||
@param preferredApiVersions: Acceptable API version(s) (e.g. vim.version.version3)
|
||||
If a list of versions is specified the versions should
|
||||
be ordered from most to least preferred.
|
||||
@type preferredApiVersions: string or string list
|
||||
"""
|
||||
|
||||
serviceVersionDescription = __GetServiceVersionDescription(protocol,
|
||||
server,
|
||||
port,
|
||||
path)
|
||||
if serviceVersionDescription is None:
|
||||
return None
|
||||
|
||||
if not isinstance(preferredApiVersions, list):
|
||||
preferredApiVersions = [ preferredApiVersions ]
|
||||
|
||||
for desiredVersion in preferredApiVersions:
|
||||
if __VersionIsSupported(desiredVersion, serviceVersionDescription):
|
||||
return desiredVersion
|
||||
return None
|
||||
|
||||
|
||||
def SmartConnect(protocol='https', host='localhost', port=443, user='root', pwd='',
|
||||
service="hostd", path="/sdk",
|
||||
preferredApiVersions=None):
|
||||
"""
|
||||
Determine the most preferred API version supported by the specified server,
|
||||
then connect to the specified server using that API version, login and return
|
||||
the service instance object.
|
||||
|
||||
Throws any exception back to caller. The service instance object is
|
||||
also saved in the library for easy access.
|
||||
|
||||
Clients should modify the service parameter only when connecting to
|
||||
a VMOMI server other than hostd/vpxd. For both of the latter, the
|
||||
default value is fine.
|
||||
|
||||
@param protocol: What protocol to use for the connection (e.g. https or http).
|
||||
@type protocol: string
|
||||
@param host: Which host to connect to.
|
||||
@type host: string
|
||||
@param port: Port
|
||||
@type port: int
|
||||
@param user: User
|
||||
@type user: string
|
||||
@param pwd: Password
|
||||
@type pwd: string
|
||||
@param service: Service
|
||||
@type service: string
|
||||
@param path: Path
|
||||
@type path: string
|
||||
@param preferredApiVersions: Acceptable API version(s) (e.g. vim.version.version3)
|
||||
If a list of versions is specified the versions should
|
||||
be ordered from most to least preferred. If None is
|
||||
specified, the list of versions support by pyVmomi will
|
||||
be used.
|
||||
@type preferredApiVersions: string or string list
|
||||
"""
|
||||
|
||||
if preferredApiVersions is None:
|
||||
preferredApiVersions = GetServiceVersions('vim25')
|
||||
|
||||
supportedVersion = __FindSupportedVersion(protocol,
|
||||
host,
|
||||
port,
|
||||
path,
|
||||
preferredApiVersions)
|
||||
if supportedVersion is None:
|
||||
raise Exception("%s:%s is not a VIM server" % (host, port))
|
||||
|
||||
portNumber = protocol == "http" and -int(port) or int(port)
|
||||
|
||||
return Connect(host=host,
|
||||
port=portNumber,
|
||||
user=user,
|
||||
pwd=pwd,
|
||||
service=service,
|
||||
adapter='SOAP',
|
||||
version=supportedVersion,
|
||||
path=path)
|
||||
|
||||
def OpenUrlWithBasicAuth(url, user='root', pwd=''):
|
||||
"""
|
||||
Open the specified URL, using HTTP basic authentication to provide
|
||||
the specified credentials to the server as part of the request.
|
||||
Returns the response as a file-like object.
|
||||
"""
|
||||
import urllib2
|
||||
pwMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
||||
pwMgr.add_password(None, url, user, pwd)
|
||||
handler = urllib2.HTTPBasicAuthHandler(pwMgr)
|
||||
opener = urllib2.build_opener(handler)
|
||||
return opener.open(url)
|
||||
|
||||
def OpenPathWithStub(path, stub):
|
||||
"""
|
||||
Open the specified path using HTTP, using the host/port/protocol
|
||||
associated with the specified stub. If the stub has a session cookie,
|
||||
it is included with the HTTP request. Returns the response as a
|
||||
file-like object.
|
||||
"""
|
||||
import httplib
|
||||
import urllib2
|
||||
if not hasattr(stub, 'scheme'):
|
||||
raise vmodl.fault.NotSupported()
|
||||
elif stub.scheme == httplib.HTTPConnection:
|
||||
protocol = 'http'
|
||||
elif stub.scheme == httplib.HTTPSConnection:
|
||||
protocol = 'https'
|
||||
else:
|
||||
raise vmodl.fault.NotSupported()
|
||||
hostPort = stub.host
|
||||
url = '%s://%s%s' % (protocol, hostPort, path)
|
||||
request = urllib2.Request(url)
|
||||
if stub.cookie:
|
||||
request.add_header('Cookie', stub.cookie)
|
||||
return urllib2.urlopen(request)
|
||||
|
||||
42
pyVmomi/Cache.py
Normal file
42
pyVmomi/Cache.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
This module implements the cache decorator
|
||||
"""
|
||||
__author__ = "VMware, Inc."
|
||||
|
||||
def Cache(fn):
|
||||
""" Function cache decorator """
|
||||
def fnCache(*args, **kwargs):
|
||||
""" Cache function """
|
||||
key = (args and tuple(args) or None,
|
||||
kwargs and frozenset(kwargs.items()) or None)
|
||||
if key not in fn.__cached__:
|
||||
fn.__cached__[key] = cache = fn(*args, **kwargs)
|
||||
else:
|
||||
cache = fn.__cached__[key]
|
||||
return cache
|
||||
|
||||
def ResetCache():
|
||||
""" Reset cache """
|
||||
fn.__cached__ = {}
|
||||
|
||||
setattr(fn, "__cached__", {})
|
||||
setattr(fn, "__resetcache__", ResetCache)
|
||||
fnCache.__name__ = fn.__name__
|
||||
fnCache.__doc__ = fn.__doc__
|
||||
fnCache.__dict__.update(fn.__dict__)
|
||||
return fnCache
|
||||
79
pyVmomi/CoreTypes.py
Normal file
79
pyVmomi/CoreTypes.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
# ******* WARNING - AUTO GENERATED CODE - DO NOT EDIT *******
|
||||
from 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")
|
||||
AddVersion("vmodl.query.version.version3", "", "", 0, "vim25")
|
||||
AddVersion("vmodl.version.version0", "", "", 0, "vim25")
|
||||
AddVersion("vmodl.version.version1", "", "", 0, "vim25")
|
||||
AddVersionParent("vmodl.query.version.version1", "vmodl.query.version.version1")
|
||||
AddVersionParent("vmodl.query.version.version1", "vmodl.version.version0")
|
||||
AddVersionParent("vmodl.query.version.version2", "vmodl.query.version.version1")
|
||||
AddVersionParent("vmodl.query.version.version2", "vmodl.query.version.version2")
|
||||
AddVersionParent("vmodl.query.version.version2", "vmodl.version.version0")
|
||||
AddVersionParent("vmodl.query.version.version2", "vmodl.version.version1")
|
||||
AddVersionParent("vmodl.query.version.version3", "vmodl.query.version.version1")
|
||||
AddVersionParent("vmodl.query.version.version3", "vmodl.query.version.version2")
|
||||
AddVersionParent("vmodl.query.version.version3", "vmodl.query.version.version3")
|
||||
AddVersionParent("vmodl.query.version.version3", "vmodl.version.version0")
|
||||
AddVersionParent("vmodl.query.version.version3", "vmodl.version.version1")
|
||||
AddVersionParent("vmodl.version.version0", "vmodl.version.version0")
|
||||
AddVersionParent("vmodl.version.version1", "vmodl.version.version0")
|
||||
AddVersionParent("vmodl.version.version1", "vmodl.version.version1")
|
||||
|
||||
CreateDataType("vmodl.DynamicArray", "DynamicArray", "vmodl.DataObject", "vmodl.version.version0", [("dynamicType", "string", "vmodl.version.version0", F_OPTIONAL), ("val", "anyType[]", "vmodl.version.version0", 0)])
|
||||
CreateDataType("vmodl.DynamicData", "DynamicData", "vmodl.DataObject", "vmodl.version.version0", [("dynamicType", "string", "vmodl.version.version0", F_OPTIONAL), ("dynamicProperty", "vmodl.DynamicProperty[]", "vmodl.version.version0", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.DynamicProperty", "DynamicProperty", "vmodl.DataObject", "vmodl.version.version0", [("name", "vmodl.PropertyPath", "vmodl.version.version0", 0), ("val", "anyType", "vmodl.version.version0", 0)])
|
||||
CreateDataType("vmodl.KeyAnyValue", "KeyAnyValue", "vmodl.DynamicData", "vmodl.version.version1", [("key", "string", "vmodl.version.version1", 0), ("value", "anyType", "vmodl.version.version1", 0)])
|
||||
CreateDataType("vmodl.LocalizableMessage", "LocalizableMessage", "vmodl.DynamicData", "vmodl.version.version1", [("key", "string", "vmodl.version.version1", 0), ("arg", "vmodl.KeyAnyValue[]", "vmodl.version.version1", F_OPTIONAL), ("message", "string", "vmodl.version.version1", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.fault.HostCommunication", "HostCommunication", "vmodl.RuntimeFault", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.HostNotConnected", "HostNotConnected", "vmodl.fault.HostCommunication", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.HostNotReachable", "HostNotReachable", "vmodl.fault.HostCommunication", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.InvalidArgument", "InvalidArgument", "vmodl.RuntimeFault", "vmodl.version.version0", [("invalidProperty", "vmodl.PropertyPath", "vmodl.version.version0", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.fault.InvalidRequest", "InvalidRequest", "vmodl.RuntimeFault", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.InvalidType", "InvalidType", "vmodl.fault.InvalidRequest", "vmodl.version.version0", [("argument", "vmodl.PropertyPath", "vmodl.version.version0", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.fault.ManagedObjectNotFound", "ManagedObjectNotFound", "vmodl.RuntimeFault", "vmodl.version.version0", [("obj", "vmodl.ManagedObject", "vmodl.version.version0", 0)])
|
||||
CreateDataType("vmodl.fault.MethodNotFound", "MethodNotFound", "vmodl.fault.InvalidRequest", "vmodl.version.version0", [("receiver", "vmodl.ManagedObject", "vmodl.version.version0", 0), ("method", "string", "vmodl.version.version0", 0)])
|
||||
CreateDataType("vmodl.fault.NotEnoughLicenses", "NotEnoughLicenses", "vmodl.RuntimeFault", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.NotImplemented", "NotImplemented", "vmodl.RuntimeFault", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.NotSupported", "NotSupported", "vmodl.RuntimeFault", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.RequestCanceled", "RequestCanceled", "vmodl.RuntimeFault", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.SecurityError", "SecurityError", "vmodl.RuntimeFault", "vmodl.version.version0", None)
|
||||
CreateDataType("vmodl.fault.SystemError", "SystemError", "vmodl.RuntimeFault", "vmodl.version.version0", [("reason", "string", "vmodl.version.version0", 0)])
|
||||
CreateDataType("vmodl.fault.UnexpectedFault", "UnexpectedFault", "vmodl.RuntimeFault", "vmodl.version.version0", [("faultName", "vmodl.TypeName", "vmodl.version.version0", 0), ("fault", "vmodl.MethodFault", "vmodl.version.version0", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.InvalidCollectorVersion", "InvalidCollectorVersion", "vmodl.MethodFault", "vmodl.query.version.version1", None)
|
||||
CreateDataType("vmodl.query.InvalidProperty", "InvalidProperty", "vmodl.MethodFault", "vmodl.query.version.version1", [("name", "vmodl.PropertyPath", "vmodl.query.version.version1", 0)])
|
||||
CreateManagedType("vmodl.query.PropertyCollector", "PropertyCollector", "vmodl.ManagedObject", "vmodl.query.version.version1", [("filter", "vmodl.query.PropertyCollector.Filter[]", "vmodl.query.version.version1", F_OPTIONAL, "System.View")], [("createFilter", "CreateFilter", "vmodl.query.version.version1", (("spec", "vmodl.query.PropertyCollector.FilterSpec", "vmodl.query.version.version1", 0, None),("partialUpdates", "boolean", "vmodl.query.version.version1", 0, None),), (0, "vmodl.query.PropertyCollector.Filter", "vmodl.query.PropertyCollector.Filter"), "System.View", ["vmodl.query.InvalidProperty", ]), ("retrieveContents", "RetrieveProperties", "vmodl.query.version.version1", (("specSet", "vmodl.query.PropertyCollector.FilterSpec[]", "vmodl.query.version.version1", 0, None),), (F_OPTIONAL, "vmodl.query.PropertyCollector.ObjectContent[]", "vmodl.query.PropertyCollector.ObjectContent[]"), "System.Anonymous", ["vmodl.query.InvalidProperty", ]), ("checkForUpdates", "CheckForUpdates", "vmodl.query.version.version1", (("version", "string", "vmodl.query.version.version1", F_OPTIONAL, None),), (F_OPTIONAL, "vmodl.query.PropertyCollector.UpdateSet", "vmodl.query.PropertyCollector.UpdateSet"), "System.View", ["vmodl.query.InvalidCollectorVersion", ]), ("waitForUpdates", "WaitForUpdates", "vmodl.query.version.version1", (("version", "string", "vmodl.query.version.version1", F_OPTIONAL, None),), (0, "vmodl.query.PropertyCollector.UpdateSet", "vmodl.query.PropertyCollector.UpdateSet"), "System.View", ["vmodl.query.InvalidCollectorVersion", ]), ("cancelWaitForUpdates", "CancelWaitForUpdates", "vmodl.query.version.version1", (), (0, "void", "void"), "System.View", None), ("waitForUpdatesEx", "WaitForUpdatesEx", "vmodl.query.version.version3", (("version", "string", "vmodl.query.version.version3", F_OPTIONAL, None),("options", "vmodl.query.PropertyCollector.WaitOptions", "vmodl.query.version.version3", F_OPTIONAL, None),), (F_OPTIONAL, "vmodl.query.PropertyCollector.UpdateSet", "vmodl.query.PropertyCollector.UpdateSet"), "System.View", ["vmodl.query.InvalidCollectorVersion", ]), ("retrievePropertiesEx", "RetrievePropertiesEx", "vmodl.query.version.version3", (("specSet", "vmodl.query.PropertyCollector.FilterSpec[]", "vmodl.query.version.version3", 0, None),("options", "vmodl.query.PropertyCollector.RetrieveOptions", "vmodl.query.version.version3", 0, None),), (F_OPTIONAL, "vmodl.query.PropertyCollector.RetrieveResult", "vmodl.query.PropertyCollector.RetrieveResult"), "System.Anonymous", ["vmodl.query.InvalidProperty", ]), ("continueRetrievePropertiesEx", "ContinueRetrievePropertiesEx", "vmodl.query.version.version3", (("token", "string", "vmodl.query.version.version3", 0, None),), (0, "vmodl.query.PropertyCollector.RetrieveResult", "vmodl.query.PropertyCollector.RetrieveResult"), "System.Anonymous", ["vmodl.query.InvalidProperty", ]), ("cancelRetrievePropertiesEx", "CancelRetrievePropertiesEx", "vmodl.query.version.version3", (("token", "string", "vmodl.query.version.version3", 0, None),), (0, "void", "void"), "System.Anonymous", ["vmodl.query.InvalidProperty", ]), ("createPropertyCollector", "CreatePropertyCollector", "vmodl.query.version.version3", (), (0, "vmodl.query.PropertyCollector", "vmodl.query.PropertyCollector"), "System.View", None), ("destroy", "DestroyPropertyCollector", "vmodl.query.version.version3", (), (0, "void", "void"), "System.View", None)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.FilterSpec", "PropertyFilterSpec", "vmodl.DynamicData", "vmodl.query.version.version1", [("propSet", "vmodl.query.PropertyCollector.PropertySpec[]", "vmodl.query.version.version1", 0), ("objectSet", "vmodl.query.PropertyCollector.ObjectSpec[]", "vmodl.query.version.version1", 0), ("reportMissingObjectsInResults", "boolean", "vmodl.query.version.version3", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.PropertySpec", "PropertySpec", "vmodl.DynamicData", "vmodl.query.version.version1", [("type", "vmodl.TypeName", "vmodl.query.version.version1", 0), ("all", "boolean", "vmodl.query.version.version1", F_OPTIONAL), ("pathSet", "vmodl.PropertyPath[]", "vmodl.query.version.version1", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.ObjectSpec", "ObjectSpec", "vmodl.DynamicData", "vmodl.query.version.version1", [("obj", "vmodl.ManagedObject", "vmodl.query.version.version1", 0), ("skip", "boolean", "vmodl.query.version.version1", F_OPTIONAL), ("selectSet", "vmodl.query.PropertyCollector.SelectionSpec[]", "vmodl.query.version.version1", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.SelectionSpec", "SelectionSpec", "vmodl.DynamicData", "vmodl.query.version.version1", [("name", "string", "vmodl.query.version.version1", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.TraversalSpec", "TraversalSpec", "vmodl.query.PropertyCollector.SelectionSpec", "vmodl.query.version.version1", [("type", "vmodl.TypeName", "vmodl.query.version.version1", 0), ("path", "vmodl.PropertyPath", "vmodl.query.version.version1", 0), ("skip", "boolean", "vmodl.query.version.version1", F_OPTIONAL), ("selectSet", "vmodl.query.PropertyCollector.SelectionSpec[]", "vmodl.query.version.version1", F_OPTIONAL)])
|
||||
CreateManagedType("vmodl.query.PropertyCollector.Filter", "PropertyFilter", "vmodl.ManagedObject", "vmodl.query.version.version1", [("spec", "vmodl.query.PropertyCollector.FilterSpec", "vmodl.query.version.version1", 0, None), ("partialUpdates", "boolean", "vmodl.query.version.version1", 0, None)], [("destroy", "DestroyPropertyFilter", "vmodl.query.version.version1", (), (0, "void", "void"), None, None)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.ObjectContent", "ObjectContent", "vmodl.DynamicData", "vmodl.query.version.version1", [("obj", "vmodl.ManagedObject", "vmodl.query.version.version1", 0), ("propSet", "vmodl.DynamicProperty[]", "vmodl.query.version.version1", F_OPTIONAL), ("missingSet", "vmodl.query.PropertyCollector.MissingProperty[]", "vmodl.query.version.version1", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.UpdateSet", "UpdateSet", "vmodl.DynamicData", "vmodl.query.version.version1", [("version", "string", "vmodl.query.version.version1", 0), ("filterSet", "vmodl.query.PropertyCollector.FilterUpdate[]", "vmodl.query.version.version1", F_OPTIONAL), ("truncated", "boolean", "vmodl.query.version.version3", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.FilterUpdate", "PropertyFilterUpdate", "vmodl.DynamicData", "vmodl.query.version.version1", [("filter", "vmodl.query.PropertyCollector.Filter", "vmodl.query.version.version1", 0), ("objectSet", "vmodl.query.PropertyCollector.ObjectUpdate[]", "vmodl.query.version.version1", F_OPTIONAL), ("missingSet", "vmodl.query.PropertyCollector.MissingObject[]", "vmodl.query.version.version1", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.ObjectUpdate", "ObjectUpdate", "vmodl.DynamicData", "vmodl.query.version.version1", [("kind", "vmodl.query.PropertyCollector.ObjectUpdate.Kind", "vmodl.query.version.version1", 0), ("obj", "vmodl.ManagedObject", "vmodl.query.version.version1", 0), ("changeSet", "vmodl.query.PropertyCollector.Change[]", "vmodl.query.version.version1", F_OPTIONAL), ("missingSet", "vmodl.query.PropertyCollector.MissingProperty[]", "vmodl.query.version.version1", F_OPTIONAL)])
|
||||
CreateEnumType("vmodl.query.PropertyCollector.ObjectUpdate.Kind", "ObjectUpdateKind", "vmodl.query.version.version1", ["modify", "enter", "leave"])
|
||||
CreateDataType("vmodl.query.PropertyCollector.Change", "PropertyChange", "vmodl.DynamicData", "vmodl.query.version.version1", [("name", "vmodl.PropertyPath", "vmodl.query.version.version1", 0), ("op", "vmodl.query.PropertyCollector.Change.Op", "vmodl.query.version.version1", 0), ("val", "anyType", "vmodl.query.version.version1", F_OPTIONAL)])
|
||||
CreateEnumType("vmodl.query.PropertyCollector.Change.Op", "PropertyChangeOp", "vmodl.query.version.version1", ["add", "remove", "assign", "indirectRemove"])
|
||||
CreateDataType("vmodl.query.PropertyCollector.MissingProperty", "MissingProperty", "vmodl.DynamicData", "vmodl.query.version.version1", [("path", "vmodl.PropertyPath", "vmodl.query.version.version1", 0), ("fault", "vmodl.MethodFault", "vmodl.query.version.version1", 0)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.MissingObject", "MissingObject", "vmodl.DynamicData", "vmodl.query.version.version1", [("obj", "vmodl.ManagedObject", "vmodl.query.version.version1", 0), ("fault", "vmodl.MethodFault", "vmodl.query.version.version1", 0)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.WaitOptions", "WaitOptions", "vmodl.DynamicData", "vmodl.query.version.version3", [("maxWaitSeconds", "int", "vmodl.query.version.version3", F_OPTIONAL), ("maxObjectUpdates", "int", "vmodl.query.version.version3", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.RetrieveOptions", "RetrieveOptions", "vmodl.DynamicData", "vmodl.query.version.version3", [("maxObjects", "int", "vmodl.query.version.version3", F_OPTIONAL)])
|
||||
CreateDataType("vmodl.query.PropertyCollector.RetrieveResult", "RetrieveResult", "vmodl.DynamicData", "vmodl.query.version.version3", [("token", "string", "vmodl.query.version.version3", F_OPTIONAL), ("objects", "vmodl.query.PropertyCollector.ObjectContent[]", "vmodl.query.version.version3", 0)])
|
||||
229
pyVmomi/Differ.py
Normal file
229
pyVmomi/Differ.py
Normal file
@@ -0,0 +1,229 @@
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
## Diff any two objects
|
||||
|
||||
from pyVmomi import VmomiSupport, types
|
||||
import itertools
|
||||
import logging
|
||||
from VmomiSupport import GetWsdlName, Type
|
||||
|
||||
__Log__ = logging.getLogger('ObjDiffer')
|
||||
|
||||
def LogIf(condition, message):
|
||||
"""Log a message if the condition is met"""
|
||||
if condition:
|
||||
__Log__.debug(message)
|
||||
|
||||
def IsPrimitiveType(obj):
|
||||
"""See if the passed in type is a Primitive Type"""
|
||||
return (isinstance(obj, types.bool) or isinstance(obj, types.byte) or
|
||||
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, types.PropertyPath) or
|
||||
isinstance(obj, types.ManagedMethod) or
|
||||
isinstance(obj, types.datetime) or
|
||||
isinstance(obj, types.URI) or isinstance(obj, type))
|
||||
|
||||
|
||||
class Differ:
|
||||
"""Class for comparing two Objects"""
|
||||
def __init__(self, looseMatch=False, ignoreArrayOrder=True):
|
||||
self._looseMatch = looseMatch
|
||||
self._ignoreArrayOrder = ignoreArrayOrder
|
||||
|
||||
def DiffAnyObjects(self, oldObj, newObj, isObjLink=False):
|
||||
"""Diff any two Objects"""
|
||||
if oldObj == newObj:
|
||||
return True
|
||||
if not oldObj or not newObj:
|
||||
__Log__.debug('DiffAnyObjects: One of the objects is unset.')
|
||||
return self._looseMatch
|
||||
oldObjInstance = oldObj
|
||||
newObjInstance = newObj
|
||||
if isinstance(oldObj, list):
|
||||
oldObjInstance = oldObj[0]
|
||||
if isinstance(newObj, list):
|
||||
newObjInstance = newObj[0]
|
||||
# Need to see if it is a primitive type first since type information
|
||||
# will not be available for them.
|
||||
if (IsPrimitiveType(oldObj) and IsPrimitiveType(newObj)
|
||||
and oldObj.__class__.__name__ == newObj.__class__.__name__):
|
||||
if oldObj == newObj:
|
||||
return True
|
||||
elif oldObj == None or newObj == None:
|
||||
__Log__.debug('DiffAnyObjects: One of the objects in None')
|
||||
return False
|
||||
oldType = Type(oldObjInstance)
|
||||
newType = Type(newObjInstance)
|
||||
if oldType != newType:
|
||||
__Log__.debug('DiffAnyObjects: Types do not match %s != %s' %
|
||||
(repr(GetWsdlName(oldObjInstance.__class__)),
|
||||
repr(GetWsdlName(newObjInstance.__class__))))
|
||||
return False
|
||||
elif isinstance(oldObj, list):
|
||||
return self.DiffArrayObjects(oldObj, newObj, isObjLink)
|
||||
elif isinstance(oldObjInstance, types.ManagedObject):
|
||||
return (not oldObj and not newObj) or (oldObj and newObj
|
||||
and oldObj._moId == newObj._moId)
|
||||
elif isinstance(oldObjInstance, types.DataObject):
|
||||
if isObjLink:
|
||||
bMatch = oldObj.GetKey() == newObj.GetKey()
|
||||
LogIf(not bMatch, 'DiffAnyObjects: Keys do not match %s != %s'
|
||||
% (oldObj.GetKey(), newObj.GetKey()))
|
||||
return bMatch
|
||||
return self.DiffDataObjects(oldObj, newObj)
|
||||
|
||||
else:
|
||||
raise TypeError("Unknown type: "+repr(GetWsdlName(oldObj.__class__)))
|
||||
|
||||
def DiffDoArrays(self, oldObj, newObj, isElementLinks):
|
||||
"""Diff two DataObject arrays"""
|
||||
if len(oldObj) != len(newObj):
|
||||
__Log__.debug('DiffDoArrays: Array lengths do not match %d != %d'
|
||||
% (len(oldObj), len(newObj)))
|
||||
return False
|
||||
for i, j in itertools.izip(oldObj, newObj):
|
||||
if isElementLinks:
|
||||
if i.GetKey() != j.GetKey():
|
||||
__Log__.debug('DiffDoArrays: Keys do not match %s != %s'
|
||||
% (i.GetKey(), j.GetKey()))
|
||||
return False
|
||||
else:
|
||||
if not self.DiffDataObjects(i, j):
|
||||
__Log__.debug(
|
||||
'DiffDoArrays: one of the elements do not match')
|
||||
return False
|
||||
return True
|
||||
|
||||
def DiffAnyArrays(self, oldObj, newObj, isElementLinks):
|
||||
"""Diff two arrays which contain Any objects"""
|
||||
if len(oldObj) != len(newObj):
|
||||
__Log__.debug('DiffAnyArrays: Array lengths do not match. %d != %d'
|
||||
% (len(oldObj), len(newObj)))
|
||||
return False
|
||||
for i, j in itertools.izip(oldObj, newObj):
|
||||
if not self.DiffAnyObjects(i, j, isElementLinks):
|
||||
__Log__.debug('DiffAnyArrays: One of the elements do not match.')
|
||||
return False
|
||||
return True
|
||||
|
||||
def DiffPrimitiveArrays(self, oldObj, newObj):
|
||||
"""Diff two primitive arrays"""
|
||||
if len(oldObj) != len(newObj):
|
||||
__Log__.debug('DiffDoArrays: Array lengths do not match %d != %d'
|
||||
% (len(oldObj), len(newObj)))
|
||||
return False
|
||||
match = True
|
||||
if self._ignoreArrayOrder:
|
||||
oldSet = oldObj and frozenset(oldObj) or frozenset()
|
||||
newSet = newObj and frozenset(newObj) or frozenset()
|
||||
match = (oldSet == newSet)
|
||||
else:
|
||||
for i, j in itertools.izip(oldObj, newObj):
|
||||
if i != j:
|
||||
match = False
|
||||
break
|
||||
if not match:
|
||||
__Log__.debug(
|
||||
'DiffPrimitiveArrays: One of the elements do not match.')
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def DiffArrayObjects(self, oldObj, newObj, isElementLinks=False):
|
||||
"""Method which deligates the diffing of arrays based on the type"""
|
||||
if oldObj == newObj:
|
||||
return True
|
||||
if not oldObj or not newObj:
|
||||
return False
|
||||
if len(oldObj) != len(newObj):
|
||||
__Log__.debug('DiffArrayObjects: Array lengths do not match %d != %d'
|
||||
% (len(oldObj), len(newObj)))
|
||||
return False
|
||||
firstObj = oldObj[0]
|
||||
if IsPrimitiveType(firstObj):
|
||||
return self.DiffPrimitiveArrays(oldObj, newObj)
|
||||
elif isinstance(firstObj, types.ManagedObject):
|
||||
return self.DiffAnyArrays(oldObj, newObj, isElementLinks)
|
||||
elif isinstance(firstObj, types.DataObject):
|
||||
return self.DiffDoArrays(oldObj, newObj, isElementLinks)
|
||||
else:
|
||||
raise TypeError("Unknown type: %s" % oldObj.__class__)
|
||||
|
||||
|
||||
def DiffDataObjects(self, oldObj, newObj):
|
||||
"""Diff Data Objects"""
|
||||
if oldObj == newObj:
|
||||
return True
|
||||
if not oldObj or not newObj:
|
||||
__Log__.debug('DiffDataObjects: One of the objects in None')
|
||||
return False
|
||||
oldType = Type(oldObj)
|
||||
newType = Type(newObj)
|
||||
if oldType != newType:
|
||||
__Log__.debug(
|
||||
'DiffDataObjects: Types do not match for dataobjects. %s != %s'
|
||||
% (oldObj._wsdlName, newObj._wsdlName))
|
||||
return False
|
||||
for prop in oldObj._GetPropertyList():
|
||||
oldProp = getattr(oldObj, prop.name)
|
||||
newProp = getattr(newObj, prop.name)
|
||||
propType = oldObj._GetPropertyInfo(prop.name).type
|
||||
if not oldProp and not newProp:
|
||||
continue
|
||||
elif ((prop.flags & VmomiSupport.F_OPTIONAL) and
|
||||
self._looseMatch and (not newProp or not oldProp)):
|
||||
continue
|
||||
elif not oldProp or not newProp:
|
||||
__Log__.debug(
|
||||
'DiffDataObjects: One of the objects has property %s unset'
|
||||
% prop.name)
|
||||
return False
|
||||
|
||||
bMatch = True
|
||||
if IsPrimitiveType(oldProp):
|
||||
bMatch = oldProp == newProp
|
||||
elif isinstance(oldProp, types.ManagedObject):
|
||||
bMatch = self.DiffAnyObjects(oldProp, newProp, prop.flags
|
||||
& VmomiSupport.F_LINK)
|
||||
elif isinstance(oldProp, types.DataObject):
|
||||
if prop.flags & VmomiSupport.F_LINK:
|
||||
bMatch = oldObj.GetKey() == newObj.GetKey()
|
||||
LogIf(not bMatch, 'DiffDataObjects: Key match failed %s != %s'
|
||||
% (oldObj.GetKey(), newObj.GetKey()))
|
||||
else:
|
||||
bMatch = self.DiffAnyObjects(oldProp, newProp, prop.flags
|
||||
& VmomiSupport.F_LINK)
|
||||
elif isinstance(oldProp, list):
|
||||
bMatch = self.DiffArrayObjects(oldProp, newProp, prop.flags
|
||||
& VmomiSupport.F_LINK)
|
||||
else:
|
||||
raise TypeError("Unknown type: "+repr(propType))
|
||||
|
||||
if not bMatch:
|
||||
__Log__.debug('DiffDataObjects: Objects differ in property %s'
|
||||
% prop.name)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def DiffAnys(obj1, obj2, looseMatch=False, ignoreArrayOrder=True):
|
||||
"""Diff any two objects. Objects can either be primitive type
|
||||
or DataObjects"""
|
||||
differ = Differ(looseMatch = looseMatch, ignoreArrayOrder = ignoreArrayOrder)
|
||||
return differ.DiffAnyObjects(obj1, obj2)
|
||||
290
pyVmomi/DynamicTypeManagerHelper.py
Normal file
290
pyVmomi/DynamicTypeManagerHelper.py
Normal file
@@ -0,0 +1,290 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
This module is a converter from dynamic type to pyVmomi type
|
||||
"""
|
||||
__author__ = "VMware, Inc."
|
||||
|
||||
from pyVmomi import VmomiSupport, vmodl
|
||||
from Cache import Cache
|
||||
|
||||
## Dynamic type importer
|
||||
#
|
||||
class DynamicTypeImporter:
|
||||
""" Dynamic type importer """
|
||||
|
||||
## Constructor
|
||||
#
|
||||
# @param stub Server stub
|
||||
def __init__(self, stub, hostSystem=None):
|
||||
self.stub = stub
|
||||
self.hostSystem = hostSystem
|
||||
|
||||
## Get dynamic type manager
|
||||
#
|
||||
# @return moRef to dynamic type manager
|
||||
@Cache
|
||||
def GetTypeManager(self):
|
||||
""" Get dynamic type manager """
|
||||
dynTypeMgr = None
|
||||
if self.hostSystem:
|
||||
try:
|
||||
dynTypeMgr = self.hostSystem.RetrieveDynamicTypeManager()
|
||||
except vmodl.fault.MethodNotFound, err:
|
||||
pass
|
||||
|
||||
if not dynTypeMgr:
|
||||
# Older host not support RetrieveDynamicTypeManager
|
||||
cmdlineTypesMoId = "ha-dynamic-type-manager"
|
||||
dynTypeMgr = vmodl.reflect.DynamicTypeManager(cmdlineTypesMoId,
|
||||
self.stub)
|
||||
return dynTypeMgr
|
||||
|
||||
## Import dynamic types
|
||||
#
|
||||
# @param prefix Only types with the specified prefix are imported
|
||||
# @return dynamic types
|
||||
@Cache
|
||||
def ImportTypes(self, prefix=''):
|
||||
""" Build dynamic types """
|
||||
# Use QueryTypeInfo to get all types
|
||||
dynTypeMgr = self.GetTypeManager()
|
||||
filterSpec = None
|
||||
if prefix != '':
|
||||
filterSpec = vmodl.reflect.DynamicTypeManager.TypeFilterSpec(
|
||||
typeSubstr=prefix)
|
||||
allTypes = dynTypeMgr.QueryTypeInfo(filterSpec)
|
||||
|
||||
## Convert dynamic types to pyVmomi types
|
||||
#
|
||||
DynamicTypeConstructor().CreateTypes(allTypes)
|
||||
return allTypes
|
||||
|
||||
|
||||
## Construct pyVmomi types from dynamic types definition
|
||||
#
|
||||
class DynamicTypeConstructor:
|
||||
""" Dynamic type constructor """
|
||||
|
||||
_mapFlags = { "optional": VmomiSupport.F_OPTIONAL,
|
||||
"linkable": VmomiSupport.F_LINKABLE,
|
||||
"link": VmomiSupport.F_LINK }
|
||||
|
||||
## Constructor
|
||||
#
|
||||
def __init__(self):
|
||||
""" Constructor """
|
||||
pass
|
||||
|
||||
## Create pyVmomi types from vmodl.reflect.DynamicTypeManager.AllTypeInfo
|
||||
#
|
||||
# @param allTypes vmodl.reflect.DynamicTypeManager.AllTypeInfo
|
||||
def CreateTypes(self, allTypes):
|
||||
"""
|
||||
Create pyVmomi types from vmodl.reflect.DynamicTypeManager.AllTypeInfo
|
||||
"""
|
||||
enumTypes, dataTypes, managedTypes = self._ConvertAllTypes(allTypes)
|
||||
self._CreateAllTypes(enumTypes, dataTypes, managedTypes)
|
||||
|
||||
## Convert all dynamic types to pyVmomi type definitions
|
||||
#
|
||||
# @param allTypes vmodl.reflect.DynamicTypeManager.AllTypeInfo
|
||||
# @return a tuple of (enumTypes, dataTypes, managedTypes)
|
||||
def _ConvertAllTypes(self, allTypes):
|
||||
""" Convert all dynamic types to pyVmomi type definitions """
|
||||
# Generate lists good for VmomiSupport.CreateXYZType
|
||||
enumTypes = self._Filter(self._ConvertEnumType, allTypes.enumTypeInfo)
|
||||
dataTypes = self._Filter(self._ConvertDataType, allTypes.dataTypeInfo)
|
||||
managedTypes = self._Filter(self._ConvertManagedType,
|
||||
allTypes.managedTypeInfo)
|
||||
retAllTypes = (enumTypes, dataTypes, managedTypes)
|
||||
return retAllTypes
|
||||
|
||||
## Create pyVmomi types from pyVmomi type definitions
|
||||
#
|
||||
# @param enumTypes pyVmomi enum type definitions
|
||||
# @param dataTypes pyVmomi data type definitions
|
||||
# @param managedTypes pyVmomi managed type definitions
|
||||
def _CreateAllTypes(self, enumTypes, dataTypes, managedTypes):
|
||||
""" Create pyVmomi types from pyVmomi type definitions """
|
||||
|
||||
# Create versions
|
||||
for typeInfo in managedTypes:
|
||||
name = typeInfo[0]
|
||||
version = typeInfo[3]
|
||||
VmomiSupport.AddVersion(version, '', '1.0', 0, name)
|
||||
VmomiSupport.AddVersionParent(version, 'vmodl.version.version0')
|
||||
VmomiSupport.AddVersionParent(version, 'vmodl.version.version1')
|
||||
VmomiSupport.AddVersionParent(version, version)
|
||||
|
||||
# Create partial types
|
||||
for fn, infos in (VmomiSupport.CreateEnumType, enumTypes), \
|
||||
(VmomiSupport.CreateDataType, dataTypes), \
|
||||
(VmomiSupport.CreateManagedType, managedTypes):
|
||||
for typeInfo in infos:
|
||||
try:
|
||||
fn(*typeInfo)
|
||||
except Exception, err:
|
||||
#Ignore errors due to duplicate importing
|
||||
pass
|
||||
|
||||
def _ConvertAnnotations(self, annotations):
|
||||
""" Convert annotations to pyVmomi flags """
|
||||
flags = 0
|
||||
if annotations:
|
||||
for annotation in annotations:
|
||||
flags |= self._mapFlags.get(annotation.name, 0)
|
||||
return flags
|
||||
|
||||
@staticmethod
|
||||
def _Filter(fn, types):
|
||||
""" Call fn for each non null element in types. Similiar to filter """
|
||||
if types:
|
||||
return [fn(prop) for prop in types if prop is not None]
|
||||
else:
|
||||
return []
|
||||
|
||||
def _ConvertParamType(self, paramType):
|
||||
"""
|
||||
Convert vmodl.reflect.DynamicTypeManager.ParamTypeInfo to pyVmomi param
|
||||
definition
|
||||
"""
|
||||
if paramType:
|
||||
name = paramType.name
|
||||
version = paramType.version
|
||||
aType = paramType.type
|
||||
flags = self._ConvertAnnotations(paramType.annotation)
|
||||
privId = paramType.privId
|
||||
param = (name, aType, version, flags, privId)
|
||||
else:
|
||||
param = None
|
||||
return param
|
||||
|
||||
def _ConvertMethodType(self, methodType):
|
||||
"""
|
||||
Convert vmodl.reflect.DynamicTypeManager.MethodTypeInfo to pyVmomi method
|
||||
definition
|
||||
"""
|
||||
if methodType:
|
||||
name = methodType.name
|
||||
wsdlName = methodType.wsdlName
|
||||
version = methodType.version
|
||||
params = self._Filter(self._ConvertParamType, methodType.paramTypeInfo)
|
||||
privId = methodType.privId
|
||||
faults = methodType.fault
|
||||
|
||||
# Figure out reture info
|
||||
if methodType.returnTypeInfo:
|
||||
returnTypeInfo = methodType.returnTypeInfo
|
||||
retFlags = self._ConvertAnnotations(returnTypeInfo.annotation)
|
||||
methodRetType = returnTypeInfo.type
|
||||
else:
|
||||
retFlags = 0
|
||||
methodRetType = "void"
|
||||
if wsdlName.endswith("_Task"):
|
||||
# TODO: Need a seperate task return type for task, instead of
|
||||
# hardcode vim.Task as return type
|
||||
retType = "vim.Task"
|
||||
else:
|
||||
retType = methodRetType
|
||||
retInfo = (retFlags, retType, methodRetType)
|
||||
|
||||
method = (name, wsdlName, version, params, retInfo, privId, faults)
|
||||
else:
|
||||
method = None
|
||||
return method
|
||||
|
||||
def _ConvertManagedPropertyType(self, propType):
|
||||
"""
|
||||
Convert vmodl.reflect.DynamicTypeManager.PropertyTypeInfo to pyVmomi
|
||||
managed property definition
|
||||
"""
|
||||
if propType:
|
||||
name = propType.name
|
||||
version = propType.version
|
||||
aType = propType.type
|
||||
flags = self._ConvertAnnotations(propType.annotation)
|
||||
privId = propType.privId
|
||||
prop = (name, aType, version, flags, privId)
|
||||
else:
|
||||
prop = None
|
||||
return prop
|
||||
|
||||
def _ConvertManagedType(self, managedType):
|
||||
"""
|
||||
Convert vmodl.reflect.DynamicTypeManager.ManagedTypeInfo to pyVmomi
|
||||
managed type definition
|
||||
"""
|
||||
if managedType:
|
||||
vmodlName = managedType.name
|
||||
wsdlName = managedType.wsdlName
|
||||
version = managedType.version
|
||||
parent = managedType.base[0]
|
||||
props = self._Filter(self._ConvertManagedPropertyType, managedType.property)
|
||||
methods = self._Filter(self._ConvertMethodType, managedType.method)
|
||||
moType = (vmodlName, wsdlName, parent, version, props, methods)
|
||||
else:
|
||||
moType = None
|
||||
return moType
|
||||
|
||||
def _ConvertDataPropertyType(self, propType):
|
||||
"""
|
||||
Convert vmodl.reflect.DynamicTypeManager.PropertyTypeInfo to pyVmomi
|
||||
data property definition
|
||||
"""
|
||||
if propType:
|
||||
name = propType.name
|
||||
version = propType.version
|
||||
aType = propType.type
|
||||
flags = self._ConvertAnnotations(propType.annotation)
|
||||
prop = (name, aType, version, flags)
|
||||
else:
|
||||
prop = None
|
||||
return prop
|
||||
|
||||
def _ConvertDataType(self, dataType):
|
||||
"""
|
||||
Convert vmodl.reflect.DynamicTypeManager.DataTypeInfo to pyVmomi data
|
||||
type definition
|
||||
"""
|
||||
if dataType:
|
||||
vmodlName = dataType.name
|
||||
wsdlName = dataType.wsdlName
|
||||
version = dataType.version
|
||||
parent = dataType.base[0]
|
||||
props = self._Filter(self._ConvertDataPropertyType, dataType.property)
|
||||
doType = (vmodlName, wsdlName, parent, version, props)
|
||||
else:
|
||||
doType = None
|
||||
return doType
|
||||
|
||||
def _ConvertEnumType(self, enumType):
|
||||
"""
|
||||
Convert vmodl.reflect.DynamicTypeManager.EnumTypeInfo to pyVmomi enum
|
||||
type definition
|
||||
"""
|
||||
if enumType:
|
||||
vmodlName = enumType.name
|
||||
wsdlName = enumType.wsdlName
|
||||
version = enumType.version
|
||||
values = enumType.value
|
||||
enumType = (vmodlName, wsdlName, version, values)
|
||||
else:
|
||||
enumType = None
|
||||
return enumType
|
||||
|
||||
356
pyVmomi/Iso8601.py
Normal file
356
pyVmomi/Iso8601.py
Normal file
@@ -0,0 +1,356 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
This module is for ISO 8601 parsing
|
||||
"""
|
||||
__author__ = 'VMware, Inc.'
|
||||
|
||||
import time
|
||||
from datetime import datetime, timedelta, tzinfo
|
||||
import re
|
||||
|
||||
""" Regular expression to parse a subset of ISO 8601 format """
|
||||
_dtExpr = re.compile(
|
||||
# XMLSchema datetime. Mandatory to have - and :
|
||||
# See: http://www.w3.org/TR/xmlschema-2/#isoformats
|
||||
# Note: python datetime cannot handle the following:
|
||||
# - leap second, ie. 0-60 seconds (not 0-59)
|
||||
# - BC (negative years)
|
||||
# year [-]0000..9999
|
||||
r'(?P<year>-?\d{4})' \
|
||||
# month 01..12
|
||||
r'(-(?P<month>(0[1-9]|1[0-2]))' \
|
||||
# day 01..31
|
||||
r'(-(?P<day>(0[1-9]|[1-2]\d|3[01])))?)?' \
|
||||
# time separator 'T'
|
||||
r'(T' \
|
||||
# hour 00..24
|
||||
r'(?P<hour>([01]\d|2[0-4]))' \
|
||||
# minute 00..59
|
||||
r'((:(?P<minute>[0-5]\d))' \
|
||||
# seconds 00..60 (leap second ok)
|
||||
r'(:(?P<second>([0-5]\d|60))' \
|
||||
# microsecond. max 16 digits
|
||||
# - Should not allows trailing zeros. But python isoformat() put zeros
|
||||
# after microseconds. Oh well, allows trailing zeros, quite harmless
|
||||
r'(\.(?P<microsecond>\d{1,16}))?)?)?' \
|
||||
# UTC 'Z', or...
|
||||
r'((?P<tzutc>Z)' \
|
||||
# tz [+-]00..13:0..59|14:00
|
||||
r'|((?P<tzhr>[+-](([0]\d)|(1[0-3])|(?P<tzlimit>)14))' \
|
||||
r'(:(?P<tzmin>(?(tzlimit)00|([0-5]\d))))?))?' \
|
||||
r')?$')
|
||||
|
||||
""" Default date time val. Key should match the tags in _dtExpr """
|
||||
_dtExprKeyDefValMap = {'year' : None, 'month' : 1, 'day' : 1,
|
||||
'hour' : 0, 'minute' : 0, 'second' : 0,
|
||||
'microsecond' : 0}
|
||||
|
||||
class TZInfo(tzinfo):
|
||||
""" Timezone info class """
|
||||
|
||||
timedelta0 = timedelta(hours=0)
|
||||
timedelta1 = timedelta(hours=1)
|
||||
|
||||
def __init__(self, tzname='UTC', utcOffset=None, dst=None):
|
||||
self._tzname = tzname
|
||||
if not utcOffset:
|
||||
utcOffset = self.timedelta0
|
||||
self._utcOffset = utcOffset
|
||||
if not dst:
|
||||
dst = None
|
||||
self._dst = dst
|
||||
|
||||
def utcoffset(self, dt):
|
||||
return self._utcOffset + self.dst(dt)
|
||||
|
||||
def tzname(self, dt):
|
||||
return self._tzname
|
||||
|
||||
def dst(self, dt):
|
||||
ret = self.timedelta0
|
||||
if self._dst:
|
||||
if self._dst[0] <= dt.replace(tzinfo=None) < self._dst[1]:
|
||||
ret = self.timedelta1
|
||||
return ret
|
||||
|
||||
|
||||
class TZManager:
|
||||
""" Time zone manager """
|
||||
_tzInfos = {}
|
||||
|
||||
@staticmethod
|
||||
def GetTZInfo(tzname='UTC', utcOffset=None, dst=None):
|
||||
""" Get / Add timezone info """
|
||||
key = (tzname, utcOffset, dst)
|
||||
tzInfo = TZManager._tzInfos.get(key)
|
||||
if not tzInfo:
|
||||
tzInfo = TZInfo(tzname, utcOffset, dst)
|
||||
TZManager._tzInfos[key] = tzInfo
|
||||
return tzInfo
|
||||
|
||||
|
||||
def ParseISO8601(datetimeStr):
|
||||
"""
|
||||
Parse ISO 8601 date time from string.
|
||||
Returns datetime if ok, None otherwise
|
||||
Note: Allows YYYY / YYYY-MM, but truncate YYYY -> YYYY-01-01,
|
||||
YYYY-MM -> YYYY-MM-01
|
||||
Truncate microsecond to most significant 6 digits
|
||||
"""
|
||||
datetimeVal = None
|
||||
match = _dtExpr.match(datetimeStr)
|
||||
if match:
|
||||
try:
|
||||
dt = {}
|
||||
for key, defaultVal in _dtExprKeyDefValMap.iteritems():
|
||||
val = match.group(key)
|
||||
if val:
|
||||
if key == 'microsecond':
|
||||
val = val[:6] + '0' * (6 - len(val))
|
||||
dt[key] = int(val)
|
||||
elif defaultVal:
|
||||
dt[key] = defaultVal
|
||||
|
||||
# Orig. XMLSchema don't allow all zeros year. But newer draft is ok
|
||||
#if dt['year'] == 0:
|
||||
# # Year cannot be all zeros
|
||||
# raise Exception('Year cannot be all zeros')
|
||||
|
||||
# 24 is a special case. It is actually represented as next day 00:00
|
||||
delta = None
|
||||
if dt.get('hour', 0) == 24:
|
||||
# Must be 24:00:00.0
|
||||
if dt.get('minute', 0) == 0 and dt.get('second', 0) == 0 and \
|
||||
dt.get('microsecond', 0) == 0:
|
||||
dt['hour'] = 23
|
||||
delta = timedelta(hours=1)
|
||||
else:
|
||||
return None
|
||||
|
||||
# Set tzinfo
|
||||
# TODO: dst
|
||||
tzInfo = None
|
||||
val = match.group('tzutc')
|
||||
if val:
|
||||
tzInfo = TZManager.GetTZInfo()
|
||||
else:
|
||||
val = match.group('tzhr')
|
||||
if val:
|
||||
# tz hours offset
|
||||
tzhr = int(val)
|
||||
utcsign = val[0]
|
||||
|
||||
# tz minutes offset
|
||||
tzmin = 0
|
||||
val = match.group('tzmin')
|
||||
if val:
|
||||
tzmin = tzhr >= 0 and int(val) or -int(val)
|
||||
|
||||
# Better tzname (map UTC +-00:00 to UTC)
|
||||
tzname = 'UTC'
|
||||
if tzhr != 0 or tzmin != 0:
|
||||
tzname += ' %s%02d:%02d' % (utcsign, abs(tzhr), abs(tzmin))
|
||||
|
||||
tzInfo = TZManager.GetTZInfo(tzname=tzname,
|
||||
utcOffset=timedelta(hours=tzhr,
|
||||
minutes=tzmin))
|
||||
if tzInfo:
|
||||
dt['tzinfo'] = tzInfo
|
||||
|
||||
datetimeVal = datetime(**dt)
|
||||
if delta:
|
||||
datetimeVal += delta
|
||||
except Exception, e:
|
||||
pass
|
||||
return datetimeVal
|
||||
|
||||
|
||||
def ISO8601Format(dt):
|
||||
"""
|
||||
Python datetime isoformat() has the following problems:
|
||||
- leave trailing 0 at the end of microseconds (violates XMLSchema rule)
|
||||
- tz print +00:00 instead of Z
|
||||
- Missing timezone offset for datetime without tzinfo
|
||||
"""
|
||||
isoStr = dt.strftime('%Y-%m-%dT%H:%M:%S')
|
||||
if dt.microsecond:
|
||||
isoStr += ('.%06d' % dt.microsecond).rstrip('0')
|
||||
if dt.tzinfo:
|
||||
tz = dt.strftime('%z')
|
||||
else:
|
||||
utcOffset_minutes = -time.altzone / 60
|
||||
tz = "%+.2d%.2d" % (utcOffset_minutes / 60, (abs(utcOffset_minutes) % 60))
|
||||
if tz == '+0000':
|
||||
return isoStr + 'Z'
|
||||
elif tz:
|
||||
return isoStr + tz[:3] + ':' + tz[3:]
|
||||
else:
|
||||
# Local offset is unknown
|
||||
return isoStr + '-00:00'
|
||||
|
||||
|
||||
# Testing
|
||||
if __name__ == '__main__':
|
||||
# Valid entries
|
||||
for testStr in [
|
||||
'1971', # 1971-01-01
|
||||
'1971-11', # 1971-11-01
|
||||
'1971-11-02',
|
||||
'1971-11-02T23',
|
||||
'1971-11-02T23Z',
|
||||
'1971-11-02T23:04',
|
||||
'1971-11-02T23:04Z',
|
||||
'1971-11-02T23:04:15',
|
||||
'1971-11-02T23:04:15Z',
|
||||
'1971-11-02T23:04:15.1',
|
||||
'1971-11-02T23:04:15.01',
|
||||
'1971-11-02T23:04:15.023456',
|
||||
'1971-11-02T23:04:15.103456Z',
|
||||
'1971-11-02T23:04:15.123456+11',
|
||||
'1971-11-02T23:04:15.123456-11',
|
||||
'1971-11-02T23:04:15.123456+11:30',
|
||||
'1971-11-02T23:04:15.123456-11:30',
|
||||
'1971-11-02T23:04:15.123456+00:00', # Same as Z
|
||||
'1971-11-02T23:04:15.123456-00:00', # Same as Z
|
||||
|
||||
'1971-01-02T23:04:15+14',
|
||||
'1971-01-02T23:04:15+14:00',
|
||||
'1971-01-02T23:04:15-14',
|
||||
'1971-01-02T23:04:15-14:00',
|
||||
|
||||
# Valid: Truncate microsec to 6 digits
|
||||
'1971-01-02T23:04:15.123456891+11',
|
||||
|
||||
'1971-01-02T24', # 24 is valid. It should represent the 00:00 the
|
||||
# next day
|
||||
'1971-01-02T24:00',
|
||||
'1971-01-02T24:00:00',
|
||||
'1971-01-02T24:00:00.0',
|
||||
|
||||
# Should NOT be valid but python isoformat adding trailing zeros
|
||||
'1971-01-02T23:04:15.123430', # Microseconds ends in zero
|
||||
'1971-01-02T23:04:15.0', # Microseconds ends in zero
|
||||
|
||||
# Should be valid but python datetime don't support it
|
||||
#'2005-12-31T23:59:60Z', # Leap second
|
||||
#'-0001', # BC 1
|
||||
]:
|
||||
dt = ParseISO8601(testStr)
|
||||
if dt == None:
|
||||
print 'Failed to parse (%s)' % testStr
|
||||
assert(False)
|
||||
|
||||
# Make sure we can translate back
|
||||
isoformat = ISO8601Format(dt)
|
||||
dt1 = ParseISO8601(isoformat)
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=dt1.tzinfo)
|
||||
if dt1 != dt:
|
||||
print 'ParseISO8601 -> ISO8601Format -> ParseISO8601 failed (%s)' % testStr
|
||||
assert(False)
|
||||
|
||||
# Make sure we can parse python isoformat()
|
||||
dt2 = ParseISO8601(dt.isoformat())
|
||||
if dt2 == None:
|
||||
print 'ParseISO8601("%s".isoformat()) failed' % testStr
|
||||
assert(False)
|
||||
|
||||
print testStr, '->', dt, isoformat
|
||||
|
||||
# Basic form
|
||||
for testStr in [
|
||||
'197111', # 1971-11-01
|
||||
'19711102',
|
||||
'19711102T23',
|
||||
'19711102T23Z',
|
||||
'19711102T2304',
|
||||
'19711102T2304Z',
|
||||
'19711102T230415',
|
||||
'19711102T230415Z',
|
||||
'19711102T230415.123456',
|
||||
'19711102T230415.123456Z',
|
||||
'19711102T230415.123456+11',
|
||||
'19711102T230415.123456-11',
|
||||
'19711102T230415.123456+1130',
|
||||
'19711102T230415.123456-1130',
|
||||
]:
|
||||
# Reject for now
|
||||
dt = ParseISO8601(testStr)
|
||||
if dt != None:
|
||||
print 'ParseISO8601 (%s) should fail, but it did not' % testStr
|
||||
assert(False)
|
||||
#print testStr, '->', dt
|
||||
#assert(dt != None)
|
||||
|
||||
# Invalid entries
|
||||
for testStr in [
|
||||
# Xml schema reject year 0
|
||||
'0000', # 0 years are not allowed
|
||||
'+0001', # Leading + is not allowed
|
||||
|
||||
'', # Empty datetime str
|
||||
'09', # Years must be at least 4 digits
|
||||
'1971-01-02T', # T not follow by time
|
||||
'1971-01-02TZ', # T not follow by time
|
||||
'1971-01-02T+10', # T not follow by time
|
||||
'1971-01-02T-10', # T not follow by time
|
||||
'1971-01-02T23:', # extra :
|
||||
'1971-01-02T23:04:', # extra :
|
||||
'1971-01-02T23:0d', # 0d
|
||||
'1971-01-02T23:04:15.', # Dot not follows by microsec
|
||||
'1971-01-02+12', # time without T
|
||||
'1971Z', # Z without T
|
||||
'1971-01-02T23:04:15.123456Z+11', # Z follows by +
|
||||
'1971-01-02T23:04:15.123456Z-11', # Z follows by -
|
||||
'1971-01-02T23:04:15.123456+:30', # extra :
|
||||
'1971-01-02T23:04:15.123456+30:', # extra :
|
||||
'1971-01-02T23:04:15.01234567890123456789', # Too many microseconds digits
|
||||
|
||||
# Python isoformat leave trailing zeros in microseconds
|
||||
# Relax regular expression to accept it
|
||||
#'1971-01-02T23:04:15.123430', # Microseconds ends in zero
|
||||
#'1971-01-02T23:04:15.0', # Microseconds ends in zero
|
||||
|
||||
# Timezone must be between +14 / -14
|
||||
'1971-01-02T23:04:15+15',
|
||||
'1971-01-02T23:04:15-15',
|
||||
'1971-01-02T23:04:15+14:01',
|
||||
'1971-01-02T23:04:15-14:01',
|
||||
|
||||
# Mix basic form with extended format
|
||||
'197101-02T23:04:15.123456',
|
||||
'19710102T23:04:15.123456',
|
||||
'19710102T230415.123456+11:30',
|
||||
'1971-01-02T230415.123456',
|
||||
'1971-01-02T23:04:15.123456+1130',
|
||||
|
||||
# Error captured by datetime class
|
||||
'1971-00-02', # Less than 1 month
|
||||
'1971-13-02', # Larger than 12 months
|
||||
'1971-01-00', # Less than 1 day
|
||||
'1971-11-32', # Larger than 30 days for Nov
|
||||
'1971-12-32', # Larger than 31 days
|
||||
'1971-01-02T24:01', # Larger than 23 hr
|
||||
'1971-01-02T23:61', # Larger than 60 min
|
||||
'1971-01-02T23:60:61', # Larger than 61 sec
|
||||
]:
|
||||
dt = ParseISO8601(testStr)
|
||||
if dt != None:
|
||||
print 'ParseISO8601 (%s) should fail, but it did not' % testStr
|
||||
assert(False)
|
||||
120
pyVmomi/ManagedMethodExecutorHelper.py
Normal file
120
pyVmomi/ManagedMethodExecutorHelper.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
This module provides convinent fns related to ManagedMethodExecutor
|
||||
"""
|
||||
__author__ = "VMware, Inc."
|
||||
|
||||
from pyVmomi import VmomiSupport, SoapAdapter, vmodl
|
||||
from SoapAdapter import SoapStubAdapterBase, Serialize, Deserialize
|
||||
|
||||
## ManagedMethodExecutor soap stub adapter
|
||||
#
|
||||
class MMESoapStubAdapter(SoapStubAdapterBase):
|
||||
""" Managed method executor stub adapter """
|
||||
|
||||
## Constructor
|
||||
#
|
||||
# The endpoint can be specified individually as either a host/port
|
||||
# combination, or with a URL (using a url= keyword).
|
||||
#
|
||||
# @param self self
|
||||
# @param mme managed method executor
|
||||
def __init__(self, mme):
|
||||
stub = mme._stub
|
||||
SoapStubAdapterBase.__init__(self, version=stub.version)
|
||||
self.mme = mme
|
||||
|
||||
## Compute the version information for the specified namespace
|
||||
#
|
||||
# @param ns the namespace
|
||||
def ComputeVersionInfo(self, version):
|
||||
SoapStubAdapterBase.ComputeVersionInfo(self, version)
|
||||
self.versionId = self.versionId[1:-1]
|
||||
|
||||
## Invoke a managed method, with _ExecuteSoap. Wohooo!
|
||||
#
|
||||
# @param self self
|
||||
# @param mo the 'this'
|
||||
# @param info method info
|
||||
# @param args arguments
|
||||
def InvokeMethod(self, mo, info, args):
|
||||
# Serialize parameters to soap parameters
|
||||
methodArgs = None
|
||||
if info.params:
|
||||
methodArgs = vmodl.Reflect.ManagedMethodExecutor.SoapArgument.Array()
|
||||
for param, arg in zip(info.params, args):
|
||||
if arg is not None:
|
||||
# Serialize parameters to soap snippets
|
||||
soapVal = Serialize(val=arg, info=param, version=self.version)
|
||||
|
||||
# Insert argument
|
||||
soapArg = vmodl.Reflect.ManagedMethodExecutor.SoapArgument(
|
||||
name=param.name, val=soapVal)
|
||||
methodArgs.append(soapArg)
|
||||
|
||||
moid = mo._GetMoId()
|
||||
version = self.versionId
|
||||
methodName = VmomiSupport.GetVmodlName(info.type) + "." + info.name
|
||||
|
||||
# Execute method
|
||||
result = self.mme.ExecuteSoap(moid=moid,
|
||||
version=version,
|
||||
method=methodName,
|
||||
argument=methodArgs)
|
||||
return self._DeserializeExecutorResult(result, info.result)
|
||||
|
||||
## Invoke a managed property accessor
|
||||
#
|
||||
# @param self self
|
||||
# @param mo the 'this'
|
||||
# @param info property info
|
||||
def InvokeAccessor(self, mo, info):
|
||||
moid = mo._GetMoId()
|
||||
version = self.versionId
|
||||
prop = info.name
|
||||
|
||||
# Fetch property
|
||||
result = self.mme.FetchSoap(moid=moid, version=version, prop=prop)
|
||||
return self._DeserializeExecutorResult(result, info.type)
|
||||
|
||||
## Deserialize result from ExecuteSoap / FetchSoap
|
||||
#
|
||||
# @param self self
|
||||
# @param result result from ExecuteSoap / FetchSoap
|
||||
# @param resultType Expected result type
|
||||
def _DeserializeExecutorResult(self, result, resultType):
|
||||
obj = None
|
||||
if result:
|
||||
# Parse the return soap snippet. If fault, raise exception
|
||||
if result.response:
|
||||
# Deserialize back to result
|
||||
obj = Deserialize(result.response, resultType, stub=self)
|
||||
elif result.fault:
|
||||
# Deserialize back to fault (or vmomi fault)
|
||||
fault = Deserialize(result.fault.faultDetail,
|
||||
object,
|
||||
stub=self)
|
||||
# Silent pylint
|
||||
raise fault # pylint: disable-msg=E0702
|
||||
else:
|
||||
# Unexpected: result should have either response or fault
|
||||
msg = "Unexpected execute/fetchSoap error"
|
||||
reason = "execute/fetchSoap did not return response or fault"
|
||||
raise vmodl.Fault.SystemError(msg=msg, reason=reason)
|
||||
return obj
|
||||
2876
pyVmomi/ServerObjects.py
Normal file
2876
pyVmomi/ServerObjects.py
Normal file
File diff suppressed because one or more lines are too long
1490
pyVmomi/SoapAdapter.py
Normal file
1490
pyVmomi/SoapAdapter.py
Normal file
File diff suppressed because it is too large
Load Diff
41
pyVmomi/StubAdapterAccessorImpl.py
Normal file
41
pyVmomi/StubAdapterAccessorImpl.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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 VmomiSupport import GetVmodlType
|
||||
|
||||
class StubAdapterAccessorMixin:
|
||||
def __init__(self):
|
||||
self._pc = None
|
||||
self._pcType = GetVmodlType("vmodl.query.PropertyCollector")
|
||||
self._siType = GetVmodlType("vim.ServiceInstance")
|
||||
|
||||
## Retrieve a managed property
|
||||
#
|
||||
# @param self self
|
||||
# @param mo managed object
|
||||
# @param info property info
|
||||
def InvokeAccessor(self, mo, info):
|
||||
filterSpec = self._pcType.FilterSpec(
|
||||
objectSet=[self._pcType.ObjectSpec(obj=mo, skip=False)],
|
||||
propSet=[self._pcType.PropertySpec(all=False, type=mo.__class__,
|
||||
pathSet=[info.name])],
|
||||
)
|
||||
## Cache the property collector if it isn't already
|
||||
# No need to lock _pc since multiple instances of PropertyCollector on
|
||||
# the client will talk to the same instance on the server.
|
||||
if not self._pc:
|
||||
si = self._siType("ServiceInstance", self)
|
||||
self._pc = si.RetrieveContent().propertyCollector
|
||||
return self._pc.RetrieveContents([filterSpec])[0].propSet[0].val
|
||||
36
pyVmomi/Version.py
Normal file
36
pyVmomi/Version.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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 VmomiSupport import nsMap, versionMap, versionIdMap, serviceNsMap, parentMap
|
||||
|
||||
## Add an API version
|
||||
def AddVersion(version, ns, versionId='', isLegacy=0, serviceNs=''):
|
||||
if not ns:
|
||||
ns = serviceNs
|
||||
if not (version in parentMap):
|
||||
nsMap[version] = ns
|
||||
if len(versionId) > 0:
|
||||
versionMap[ns + '/' + versionId] = version
|
||||
if isLegacy or ns is "":
|
||||
versionMap[ns] = version
|
||||
versionIdMap[version] = versionId
|
||||
if not serviceNs:
|
||||
serviceNs = ns
|
||||
serviceNsMap[version] = serviceNs
|
||||
parentMap[version] = {}
|
||||
|
||||
## Check if a version is a child of another
|
||||
def IsChildVersion(child, parent):
|
||||
return child == parent or parent in parentMap[child]
|
||||
1630
pyVmomi/VmomiSupport.py
Normal file
1630
pyVmomi/VmomiSupport.py
Normal file
File diff suppressed because it is too large
Load Diff
227
pyVmomi/__init__.py
Normal file
227
pyVmomi/__init__.py
Normal file
@@ -0,0 +1,227 @@
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
# 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
|
||||
# version or more.
|
||||
import sys
|
||||
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
|
||||
try:
|
||||
import ReflectTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import ServerObjects
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import InternalServerObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Import all the known product-specific types
|
||||
# XXX: Make this search the package for types?
|
||||
try:
|
||||
import DrObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import DrextObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import HbrReplicaTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import HmsObjects
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import HostdObjects
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import VpxObjects
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import VorbTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import DodoTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import VmwauthproxyTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import DmsTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import OmsTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import HmoTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import CimsfccTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import TaskupdaterTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import ImgFactTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import VpxapiTypes
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import CsiObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import HostdTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import TaggingObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import NfcTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import SmsObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import SpsObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import DataserviceObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Start of update manager specific types
|
||||
try:
|
||||
import IntegrityObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import SysimageObjects
|
||||
except ImportError:
|
||||
pass
|
||||
# End of update manager specific types
|
||||
|
||||
try:
|
||||
import RbdTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Import Profile based management specific VMODL
|
||||
try:
|
||||
import PbmObjects
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import CisLicenseTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import TestTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import SsoTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import CisCmTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import DataserviceTypes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
# All data object types and fault types have DynamicData as an ancestor
|
||||
# As well load it proactively.
|
||||
# Note: This should be done before importing SoapAdapter as it uses
|
||||
# some fault types
|
||||
VmomiSupport.GetVmodlType("vmodl.DynamicData")
|
||||
|
||||
from SoapAdapter import SoapStubAdapter, StubAdapterBase, SoapCmdStubAdapter, \
|
||||
SessionOrientedStub
|
||||
|
||||
types = VmomiSupport.types
|
||||
|
||||
# This will allow files to use Create** functions
|
||||
# directly from pyVmomi
|
||||
CreateEnumType = VmomiSupport.CreateEnumType
|
||||
CreateDataType = VmomiSupport.CreateDataType
|
||||
CreateManagedType = VmomiSupport.CreateManagedType
|
||||
|
||||
# For all the top level names, creating a LazyModule object
|
||||
# in the global namespace of pyVmomi. Files can just import the
|
||||
# top level namespace and we will figure out what to load and when
|
||||
# Examples:
|
||||
# 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)
|
||||
_globals[name] = obj
|
||||
if VmomiSupport._allowCapitalizedNames:
|
||||
_globals[upperCaseName] = obj
|
||||
if not hasattr(VmomiSupport.types, name):
|
||||
setattr(VmomiSupport.types, name, obj)
|
||||
if VmomiSupport._allowCapitalizedNames:
|
||||
setattr(VmomiSupport.types, upperCaseName, obj)
|
||||
del _globals
|
||||
17
pyVmomi/pyVmomiSettings.py
Normal file
17
pyVmomi/pyVmomiSettings.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
allowGetSet = False
|
||||
allowCapitalizedNames = False
|
||||
4
pyvmomi.egg-info/.gitignore
vendored
Normal file
4
pyvmomi.egg-info/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
PKG-INFO
|
||||
sources.txt
|
||||
dependency_links.txt
|
||||
zip-safe
|
||||
2
pyvmomi.egg-info/top_level.txt
Normal file
2
pyvmomi.egg-info/top_level.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
pyVim
|
||||
pyVmomi
|
||||
110
sample/getallvms.py
Normal file
110
sample/getallvms.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/python
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Python program for listing the vms on an ESX / vCenter host
|
||||
"""
|
||||
|
||||
from optparse import OptionParser, make_option
|
||||
from pyVim.connect import SmartConnect, Disconnect
|
||||
from pyVmomi import vmodl
|
||||
import sys
|
||||
import atexit
|
||||
|
||||
def GetOptions():
|
||||
"""
|
||||
Supports the command-line arguments listed below.
|
||||
"""
|
||||
|
||||
_CMD_OPTIONS_LIST = [
|
||||
make_option("-h", "--host",
|
||||
help="remote host to connect to"),
|
||||
make_option("-o", "--port",
|
||||
default=443,
|
||||
help="Port"),
|
||||
make_option("-u", "--user",
|
||||
default="root",
|
||||
help="User name to use when connecting to host"),
|
||||
make_option("-p", "--password",
|
||||
help="Password to use when connecting to host"),
|
||||
make_option("-?", "--help", action="store_true",
|
||||
help="Help"),
|
||||
]
|
||||
_STR_USAGE = "%prog [options]"
|
||||
|
||||
parser = OptionParser(option_list=_CMD_OPTIONS_LIST,
|
||||
usage=_STR_USAGE,
|
||||
add_help_option=False)
|
||||
(options, _) = parser.parse_args()
|
||||
|
||||
return options
|
||||
|
||||
def PrintVmInfo(vm):
|
||||
"""
|
||||
Print information for a particular virtual machine.
|
||||
"""
|
||||
|
||||
summary = vm.summary
|
||||
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
|
||||
if summary.guest != None:
|
||||
ip = summary.guest.ipAddress
|
||||
if ip != None and ip != "":
|
||||
print "IP : ", ip
|
||||
if summary.runtime.question != None:
|
||||
print "Question : ", summary.runtime.question.text
|
||||
print ""
|
||||
|
||||
def main():
|
||||
"""
|
||||
Simple command-line program for listing the virtual machines on a system.
|
||||
"""
|
||||
|
||||
options = GetOptions()
|
||||
try:
|
||||
si = SmartConnect(host=options.host,
|
||||
user=options.user,
|
||||
pwd=options.password,
|
||||
port=int(options.port))
|
||||
if not si:
|
||||
print "Could not connect to the specified host"
|
||||
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
|
||||
|
||||
return 0
|
||||
|
||||
# Start program
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
154
sample/poweronvm.py
Executable file
154
sample/poweronvm.py
Executable file
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# VMware vSphere Python SDK
|
||||
# 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
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Python program for powering on vms on a host on which hostd is running
|
||||
"""
|
||||
|
||||
from optparse import OptionParser, make_option
|
||||
from pyVim.connect import SmartConnect, Disconnect
|
||||
from pyVmomi import vim, vmodl
|
||||
import sys
|
||||
import atexit
|
||||
|
||||
def GetOptions():
|
||||
"""
|
||||
Supports the command-line arguments listed below.
|
||||
"""
|
||||
|
||||
_CMD_OPTIONS_LIST = [
|
||||
make_option("-h", "--host",
|
||||
help="remote host to connect to"),
|
||||
make_option("-o", "--port",
|
||||
default=443,
|
||||
help="Port"),
|
||||
make_option("-u", "--user",
|
||||
default="root",
|
||||
help="User name to use when connecting to host"),
|
||||
make_option("-p", "--password",
|
||||
help="Password to use when connecting to host"),
|
||||
make_option("-v", "--vmname", default=[], action="append",
|
||||
help="Name of the Virtual Machine to power on"),
|
||||
make_option("-?", "--help", action="store_true",
|
||||
help="Help"),
|
||||
]
|
||||
_STR_USAGE = "%prog [options]"
|
||||
|
||||
parser = OptionParser(option_list=_CMD_OPTIONS_LIST,
|
||||
usage=_STR_USAGE,
|
||||
add_help_option=False)
|
||||
(options, _) = parser.parse_args()
|
||||
return options
|
||||
|
||||
def WaitForTasks(tasks, si):
|
||||
"""
|
||||
Given the service instance si and tasks, it returns after all the
|
||||
tasks are complete
|
||||
"""
|
||||
|
||||
pc = si.content.propertyCollector
|
||||
|
||||
taskList = [str(task) for task in tasks]
|
||||
|
||||
# Create filter
|
||||
objSpecs = [vmodl.query.PropertyCollector.ObjectSpec(obj=task)
|
||||
for task in tasks]
|
||||
propSpec = vmodl.query.PropertyCollector.PropertySpec(type=vim.Task,
|
||||
pathSet=[], all=True)
|
||||
filterSpec = vmodl.query.PropertyCollector.FilterSpec()
|
||||
filterSpec.objectSet = objSpecs
|
||||
filterSpec.propSet = [propSpec]
|
||||
filter = pc.CreateFilter(filterSpec, True)
|
||||
|
||||
try:
|
||||
version, state = None, None
|
||||
|
||||
# Loop looking for updates till the state moves to a completed state.
|
||||
while len(taskList):
|
||||
update = pc.WaitForUpdates(version)
|
||||
for filterSet in update.filterSet:
|
||||
for objSet in filterSet.objectSet:
|
||||
task = objSet.obj
|
||||
for change in objSet.changeSet:
|
||||
if change.name == 'info':
|
||||
state = change.val.state
|
||||
elif change.name == 'info.state':
|
||||
state = change.val
|
||||
else:
|
||||
continue
|
||||
|
||||
if not str(task) in taskList:
|
||||
continue
|
||||
|
||||
if state == vim.TaskInfo.State.success:
|
||||
# Remove task from taskList
|
||||
taskList.remove(str(task))
|
||||
elif state == vim.TaskInfo.State.error:
|
||||
raise task.info.error
|
||||
# Move to next version
|
||||
version = update.version
|
||||
finally:
|
||||
if filter:
|
||||
filter.Destroy()
|
||||
|
||||
# Start program
|
||||
def main():
|
||||
"""
|
||||
Simple command-line program for powering on virtual machines on a system.
|
||||
"""
|
||||
|
||||
options = GetOptions()
|
||||
try:
|
||||
vmnames = options.vmname
|
||||
if not len(vmnames):
|
||||
print "No virtual machine specified for poweron"
|
||||
sys.exit()
|
||||
|
||||
si = SmartConnect(host=options.host,
|
||||
user=options.user,
|
||||
pwd=options.password,
|
||||
port=int(options.port))
|
||||
if not si:
|
||||
print "Cannot connect to Host"
|
||||
sys.exit()
|
||||
|
||||
atexit.register(Disconnect, si)
|
||||
|
||||
# Retreive the list of Virtual Machines from the invetory objects
|
||||
# under the rootFolder
|
||||
content = si.content
|
||||
objView = content.viewManager.CreateContainerView(content.rootFolder,
|
||||
[vim.VirtualMachine],
|
||||
True)
|
||||
vmList = objView.view
|
||||
objView.Destroy()
|
||||
|
||||
# Find the vm and power it on
|
||||
tasks = [vm.PowerOn() for vm in vmList if vm.name in vmnames]
|
||||
|
||||
# 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)
|
||||
|
||||
# Start program
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
42
setup.py
Normal file
42
setup.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# VMware vSphere Python SDK
|
||||
# Copyright (c) 2009-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
|
||||
#
|
||||
# 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 setuptools import setup
|
||||
import os
|
||||
|
||||
def read(fname):
|
||||
return open(os.path.join(os.path.dirname(__file__), fname)).read()
|
||||
|
||||
setup(
|
||||
name='pyvmomi',
|
||||
version='5.1.0',
|
||||
description='VMware vSphere Python SDK',
|
||||
author='VMware, Inc.',
|
||||
author_email='jhu@vmware.com',
|
||||
url='https://github.com/vmware/pyvmomi',
|
||||
packages=['pyVmomi', 'pyVim'],
|
||||
license='Apache',
|
||||
long_description=read('README.md'),
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Development Status :: 4 - Beta",
|
||||
"Environment :: No Input/Output (Daemon)",
|
||||
"Intended Audience :: Information Technology",
|
||||
"Intended Audience :: System Administrators",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Topic :: System :: Distributed Computing"
|
||||
],
|
||||
zip_safe=True
|
||||
)
|
||||
Reference in New Issue
Block a user