1
0
mirror of https://github.com/vmware/vsphere-automation-sdk-python.git synced 2024-11-22 17:39:59 -05:00
vsphere-automation-sdk-python/samples/vsphere/common/vim/datastore_file.py
Tianhao He ba26a070a6 Fix typo in license text
Signed-off-by: Tianhao He <het@vmware.com>
2017-03-15 15:36:13 -07:00

344 lines
10 KiB
Python

"""
* *******************************************************
* Copyright (c) VMware, Inc. 2016. All Rights Reserved.
* SPDX-License-Identifier: MIT
* *******************************************************
*
* 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.
"""
__author__ = 'VMware, Inc.'
__copyright__ = 'Copyright 2016 VMware, Inc. All rights reserved.'
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 is not 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 is not None:
f = src_file
elif src_url is not None:
f = requests.get(src_url, stream=True)
elif src_path is not None:
f = open(src_file, 'wb')
elif content is 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)