1
0
mirror of https://github.com/vmware/vsphere-automation-sdk-python.git synced 2024-11-23 09:59:59 -05:00
vsphere-automation-sdk-python/samples/vsphere/common/vim/datastore_file.py
Tianhao He b3bea5c03d Adjust the folder strucuture to match what's like in Java project.
1. Move folders around.
2. Remove samples.cfg
3. Remove inventory sample as it's replaced by contentlibrary samples
4. Update README.md under samples/vsphere
2017-01-23 16:50:20 -08:00

340 lines
10 KiB
Python

"""
* *******************************************************
* Copyright (c) VMware, Inc. 2016. All Rights Reserved.
* *******************************************************
*
* DISCLAIMER. THIS PROGRAM IS PROVIDED TO YOU "AS IS" WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, WHETHER ORAL OR WRITTEN,
* EXPRESS OR IMPLIED. THE AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED
* WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY,
* NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
"""
import pyVim.task
import requests
from pyVmomi import vim
from samples.vsphere.common.vim.inventory import get_datacenter_for_datastore
# TODO:
# verify=False in all cases. Expose this as a top level control
debug = False
(FILE, FOLDER) = range(2)
class FileArray(list):
def list(self, path=None):
children = FileArray()
for e in self:
children += e.list(path)
return children
def __repr__(self):
return '\n'.join([str(e) for e in self])
def _check_unique(self):
if len(self) == 0:
raise Exception('FileArray: No elements')
elif len(self) > 1:
raise Exception('FileArray: Maybe applied to only one element')
@property
def path(self):
self._check_unique()
return self[0].path
@property
def datastore_path(self):
self._check_unique()
return self[0].datastore_path
@property
def datastore_mo(self):
self._check_unique()
return self[0].datastore_mo
@property
def type(self):
self._check_unique()
return self[0].type
def list(self, path=None):
self._check_unique()
return self[0].list(path)
def put(self, path=None, src_url=None, src_file=None, src_path=None,
content=None):
self._check_unique()
return self[0].put(path, src_url, src_file, src_path, content)
def get(self, path=None):
self._check_unique()
return self[0].get(path)
def exists(self, path=None):
self._check_unique()
return self[0].exists(path)
def delete(self, path=None):
self._check_unique()
return self[0].delete(path)
def delete2(self, path=None):
self._check_unique()
return self[0].delete2(path)
def mkdir(self, path=None, parent=None):
self._check_unique()
return self[0].mkdir(path, parent)
class File(object):
"""
Utility class contains datastore related helper methods using vim API
and HTTP requests module.
"""
def __init__(self, parent=None, path=None, ftype=None):
self._file_manager = None
if isinstance(parent, vim.Datastore):
# Iteratively look for the Datacenter parent
self._datacenter_mo = get_datacenter_for_datastore(parent)
self._datastore_mo = parent
self._ftype = FOLDER
if path:
self._path = path
else:
self._path = ''
elif isinstance(parent, File):
self._datacenter_mo = parent._datacenter_mo
self._datastore_mo = parent.datastore_mo
self._ftype = ftype
if parent._path == '':
self._path = path
else:
self._path = '{}/{}'.format(parent._path, path)
else:
raise Exception(
"Invalid type '{}' for datastore_file".format(type(parent)))
def _get_file_manager(self):
if not self._file_manager:
soap_stub = self._datacenter_mo._stub
service_instance = vim.ServiceInstance('ServiceInstance', soap_stub)
self._file_manager = service_instance.content.fileManager
return self._file_manager
@property
def path(self):
return self._path
@path.setter
def path(self, value):
self._path = value
def get_datastore_path(self, path=None):
if not path:
return self.datastore_path
paths = [p for p in [self._path, path] if p]
return '[{}] {}'.format(self._datastore_mo.name, '/'.join(paths))
@property
def datastore_path(self):
if self._path != '':
return '[{}] {}'.format(self._datastore_mo.name, self._path)
else:
return '[{}]'.format(self._datastore_mo.name)
@property
def datastore_mo(self):
return self._datastore_mo
@datastore_mo.setter
def datastore_mo(self, value):
self._datastore_mo = value
@property
def type(self):
return self._ftype
@type.setter
def type(self, value):
self._ftype = value
def to_string(self):
s = ''
if self._ftype == FOLDER:
s += 'D '
else:
s += 'F '
s += self.datastore_path
return s
def __repr__(self):
return self.to_string()
def list(self, path=None):
match_pattern = None
dirname = None
if path != None:
# Determine the dirname and the basename making sure only the
# basename is passed in the match_pattern
paths = path.split('/')
if len(paths) == 1:
dirname = paths[0]
else:
path = paths[-1]
dirname = '/'.join(paths[0:-1])
match_pattern = [path]
browser = self._datastore_mo.browser
search_spec = vim.host.DatastoreBrowser.SearchSpec(
query=[vim.host.DatastoreBrowser.FolderQuery(),
vim.host.DatastoreBrowser.Query()],
details=vim.host.DatastoreBrowser.FileInfo.Details(fileType=True),
matchPattern=match_pattern,
sortFoldersFirst=True)
if debug:
print("list: dirname='{}' search_spec='{}'".
format(dirname, search_spec))
task = browser.Search(dirname, search_spec)
pyVim.task.WaitForTask(task)
children = FileArray()
for f in task.info.result.file:
ftype = FILE
if isinstance(f, vim.host.DatastoreBrowser.FolderInfo):
ftype = FOLDER
if dirname:
children.append(
File(self, path='/'.join([dirname, f.path]), ftype=ftype))
else:
children.append(File(self, path=f.path, ftype=ftype))
return children
def _make_cookie(self, stub):
cookies = {}
for c in stub.cookie.split(';'):
e = c.strip().split('=')
if len(e) > 1:
cookies[e[0]] = e[1]
return cookies
def exists(self, path=None):
try:
return len(self.list(path)) > 0
except vim.fault.FileNotFound:
return False
def put(self, path=None, src_url=None, src_file=None, src_path=None,
content=None):
datacenter_name = self._datacenter_mo.name
datastore_name = self._datastore_mo.name
stub = self._datastore_mo._stub
cookie = self._make_cookie(stub)
f = None
if src_file != None:
f = src_file
elif src_url != None:
f = requests.get(src_url, stream=True)
elif src_path != None:
f = open(src_file, 'wb')
elif content == None:
raise Exception('No input provided for put')
if f:
data = f
else:
data = content
paths = ['https://{0}/folder'.format(stub.host)]
if self._path:
paths.append(self._path)
if path:
paths.append(path)
url = '/'.join(paths)
if debug:
print("put: url is '{}'".format(url))
r = requests.put(url, params={'dcPath': datacenter_name,
'dsName': datastore_name},
cookies=cookie, verify=False, data=data)
if f:
f.close()
f = None
if r.status_code < 200 or r.status_code >= 300:
raise Exception('Put failed with status {}'.format(r.status_code),
r)
def get(self, path=None):
datacenter_name = self._datacenter_mo.name
datastore_name = self._datastore_mo.name
stub = self._datastore_mo._stub
cookie = self._make_cookie(stub)
paths = ['https://{0}/folder'.format(stub.host)]
if self._path:
paths.append(self._path)
if path:
paths.append(path)
url = '/'.join(paths)
if debug:
print("get: url is '{}'".format(url))
r = requests.get(url, params={'dcPath': datacenter_name,
'dsName': datastore_name},
cookies=cookie, verify=False, stream=True)
if r.status_code < 200 or r.status_code >= 300:
raise Exception('Get failed with status {}'.format(r.status_code),
r)
return r
def delete(self, path=None):
datacenter_name = self._datacenter_mo.name
datastore_name = self._datastore_mo.name
stub = self._datastore_mo._stub
cookie = self._make_cookie(stub)
paths = ['https://{0}/folder'.format(stub.host)]
if self._path:
paths.append(self._path)
if path:
paths.append(path)
url = '/'.join(paths)
if debug:
print("delete: url is '{}'".format(url))
r = requests.delete(url, params={'dcPath': datacenter_name,
'dsName': datastore_name},
cookies=cookie, verify=False)
if r.status_code < 200 or r.status_code >= 300:
raise Exception(
'Delete failed with status {}'.format(r.status_code), r)
def delete2(self, path=None):
datacenter_mo = self._datacenter_mo
file_manager = self._get_file_manager()
datastore_path = self.get_datastore_path(path)
if debug:
print("delete2: datastore_path is '{}'".format(datastore_path))
# TODO 'FileType' is not public?
# file_manager.Delete(self._datacenter_mo, datastore_path, 'File')
def mkdir(self, path=None, parent=False):
datacenter_mo = self._datacenter_mo
file_manager = self._get_file_manager()
datastore_path = self.get_datastore_path(path)
if debug:
print("mkdir: datastore_path is '{}'".format(datastore_path))
file_manager.MakeDirectory(datastore_path, self._datacenter_mo, parent)