有个需求,用户通过浏览器页面上传文件到datastore(我们事先有跟VCenter建立连接),似乎Vmware Vsphere WebService SDK似乎没有提供接口。挖了下oslo.vmware的代码发现有实现。我们先看下用法:
from oslo_vmware import rw_handles
import os
from oslo_vmware import api
def upload_iso_to_datastore(session,iso_path, dest_file, ds_name,dc_name,host,port=443):
cookies = session.vim.client.options.transport.cookiejar
with open(iso_path, 'r') as iso_file:
write_file_handle = rw_handles.FileWriteHandle(
host,
port,
dc_name,
ds_name,
cookies,
dest_file,
os.fstat(iso_file.fileno()).st_size)
block_size = 0x10000
data = iso_file.read(block_size)
while len(data) > 0:
write_file_handle.write(data)
data = iso_file.read(block_size)
write_file_handle.close()
session = api.VMwareAPISession(
'192.168.3.249', # vSphere host endpoint
'[email protected]', # vSphere username
'123456$xx', # vSphere password
10, # Number of retries for connection failures in tasks
0.1 # Poll interval for async tasks (in seconds)
)
upload_iso_to_datastore(session,"/opt/test.iso","test.iso","datastore1","192.168.3.254")
很容易搞明白,跟VCenter连接连接,获取cookies,然后调用rw_handles的FileWriteHandle类实现。
我看下该类的实现:
class FileWriteHandle(FileHandle):
"""Write handle for a file in VMware server."""
def __init__(self, host, port, data_center_name, datastore_name, cookies,
file_path, file_size, scheme='https', cacerts=False,
thumbprint=None):
"""Initializes the write handle with given parameters.
:param host: ESX/VC server IP address or host name
:param port: port for connection
:param data_center_name: name of the data center in the case of a VC
server
:param datastore_name: name of the datastore where the file is stored
:param cookies: cookies to build the vim cookie header
:param file_path: datastore path where the file is written
:param file_size: size of the file in bytes
:param scheme: protocol-- http or https
:param cacerts: CA bundle file to use for SSL verification
:param thumbprint: expected SHA1 thumbprint of server's certificate
:raises: VimConnectionException, ValueError
"""
soap_url = self._get_soap_url(scheme, host, port)
param_list = {'dcPath': data_center_name, 'dsName': datastore_name}
self._url = '%s/folder/%s' % (soap_url, file_path)
self._url = self._url + '?' + urlparse.urlencode(param_list)
self._conn = self._create_write_connection('PUT',
self._url,
file_size,
cookies=cookies,
cacerts=cacerts,
ssl_thumbprint=thumbprint)
FileHandle.__init__(self, self._conn)
def write(self, data):
"""Write data to the file.
:param data: data to be written
:raises: VimConnectionException, VimException
"""
try:
self._file_handle.send(data)
except requests.RequestException as excep:
excep_msg = _("Connection error occurred while writing data to"
" %s.") % self._url
LOG.exception(excep_msg)
raise exceptions.VimConnectionException(excep_msg, excep)
except Exception as excep:
# TODO(vbala) We need to catch and raise specific exceptions
# related to connection problems, invalid request and invalid
# arguments.
excep_msg = _("Error occurred while writing data to"
" %s.") % self._url
LOG.exception(excep_msg)
raise exceptions.VimException(excep_msg, excep)
def close(self):
"""Get the response and close the connection."""
LOG.debug("Closing write handle for %s.", self._url)
try:
self._conn.getresponse()
except Exception:
LOG.warning(_LW("Error occurred while reading the HTTP response."),
exc_info=True)
super(FileWriteHandle, self).close()
def __str__(self):
return "File write handle for %s" % self._url
可以看到就是上传文件到某个url,一般形式是:
https://192.168.3.249:443/folder/{路径/文件名}?dsName={存储器ing}&dcPath={数据中心名}
是不是很简单?