X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;ds=inline;f=tools%2Fvmware_ovf_upload.py;fp=tools%2Fvmware_ovf_upload.py;h=0000000000000000000000000000000000000000;hb=e5245336823411b71968e72c32b3bf33cc07638f;hp=834068de6501dcd717a42391f94141ee4a8b2f01;hpb=84fe31f632166d2fbf566968bd25aa9545e96fdc;p=osm%2Fdevops.git diff --git a/tools/vmware_ovf_upload.py b/tools/vmware_ovf_upload.py deleted file mode 100755 index 834068de..00000000 --- a/tools/vmware_ovf_upload.py +++ /dev/null @@ -1,329 +0,0 @@ -# -*- coding: utf-8 -*- - -# # -# Copyright 2016-2017 VMware Inc. -# This file is part of ETSI OSM -# 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. -# -# For those usages not covered by the Apache License, Version 2.0 please -# contact: osslegalrouting@vmware.com -# # - -import logging -import os -from progressbar import Percentage, Bar, ETA, FileTransferSpeed, ProgressBar -from pyvcloud.vcd.client import BasicLoginCredentials, Client -from pyvcloud.vcd.org import Org -import re -import requests -import sys -import time -from xml.etree import ElementTree as XmlElementTree - -API_VERSION = '5.6' - - -class vCloudconfig(object): - - def __init__(self, host=None, user=None, password=None, orgname=None, logger=None): - self.url = host - self.user = user - self.password = password - self.org = orgname - self.logger = logging.getLogger('vmware_ovf_upload') - self.logger.setLevel(10) - - def connect(self): - """ Method connect as normal user to vCloud director. - - Returns: - The return vca object that letter can be used to connect to vCloud director as admin for VDC - """ - - try: - self.logger.debug("Logging in to a vcd {} as user {}".format(self.org, - self.user)) - client = Client(self.url, verify_ssl_certs=False) - client.set_credentials(BasicLoginCredentials(self.user, self.org, self.password)) - except Exception: - raise Exception("Can't connect to a vCloud director org: " - "{} as user: {}".format(self.org, self.user)) - - return client - - def get_catalog_id_from_path(self, catalog_name=None, path=None, progress=False): - """ - Args - catalog - catalog name to be created - path: - valid path to OVF file. - progress - boolean progress bar show progress bar. - - Return: if image uploaded correct method will provide image catalog UUID. - """ - if not path: - raise Exception("Image path can't be None.") - - if not os.path.isfile(path): - raise Exception("Can't read file. File not found.") - - if not os.access(path, os.R_OK): - raise Exception("Can't read file. Check file permission to read.") - - self.logger.debug("get_catalog_id_from_path() client requesting {} ".format(path)) - - _, filename = os.path.split(path) - _, file_extension = os.path.splitext(path) - if file_extension != '.ovf': - self.logger.debug("Wrong file extension {} connector support only OVF container.".format(file_extension)) - raise Exception("Wrong container. vCloud director supports only OVF.") - - self.logger.debug("File name {} Catalog Name {} file path {} ".format(filename, - catalog_name, - path)) - try: - client = self.connect() - if not client: - raise Exception("Failed to connect vCD") - org = Org(client, resource=client.get_org()) - catalogs = org.list_catalogs() - except Exception as exp: - self.logger.debug("Failed get catalogs() with Exception {} ".format(exp)) - raise Exception("Failed get catalogs() with Exception {} ".format(exp)) - - if len(catalogs) == 0: - self.logger.info("Creating a new catalog entry {} in vcloud director".format(catalog_name)) - result = org.create_catalog(catalog_name, catalog_name) - if result is None: - raise Exception("Failed to create new catalog {} ".format(catalog_name)) - result = self.upload_ovf(org=org, catalog_name=catalog_name, image_name=filename.split(".")[0], - media_file_name=path, description='medial_file_name', progress=progress) - if not result: - raise Exception("Failed to create vApp template for catalog {} ".format(catalog_name)) - return self.get_catalogid(catalog_name, catalogs) - else: - for catalog in catalogs: - # search for existing catalog if we find same name we return ID - if catalog['name'] == catalog_name: - self.logger.debug("Found existing catalog entry for {} " - "catalog id {}".format(catalog_name, - self.get_catalogid(catalog_name, catalogs))) - return self.get_catalogid(catalog_name, catalogs) - - # if we didn't find existing catalog we create a new one and upload image. - self.logger.debug("Creating new catalog entry {} - {}".format(catalog_name, catalog_name)) - result = org.create_catalog(catalog_name, catalog_name) - if result is None: - raise Exception("Failed to create new catalog {} ".format(catalog_name)) - - result = self.upload_ovf(org=org, catalog_name=catalog_name, image_name=filename.split(".")[0], - media_file_name=path, description='medial_file_name', progress=progress) - if not result: - raise Exception("Failed create vApp template for catalog {} ".format(catalog_name)) - - def get_catalogid(self, catalog_name=None, catalogs=None): - """ Method check catalog and return catalog ID in UUID format. - - Args - catalog_name: catalog name as string - catalogs: list of catalogs. - - Return: catalogs uuid - """ - - for catalog in catalogs: - if catalog['name'] == catalog_name: - catalog_id = catalog['id'] - return catalog_id - return None - - def upload_ovf(self, org=None, catalog_name=None, image_name=None, media_file_name=None, - description='', progress=False, chunk_bytes=128 * 1024): - """ - Uploads a OVF file to a vCloud catalog - - org : organization object - catalog_name: (str): The name of the catalog to upload the media. - media_file_name: (str): The name of the local media file to upload. - return: (bool) True if the media file was successfully uploaded, false otherwise. - """ - client = self.connect() - if not client: - raise Exception("Failed to connect vCD!") - - os.path.isfile(media_file_name) - statinfo = os.stat(media_file_name) - - # find a catalog entry where we upload OVF. - # create vApp Template and check the status if vCD able to read OVF it will respond with appropirate - # status change. - # if VCD can parse OVF we upload VMDK file - try: - for catalog in org.list_catalogs(): - if catalog_name != catalog['name']: - continue - catalog_href = "{}/api/catalog/{}/action/upload".format(self.url, catalog['id']) - data = """ - - {} vApp Template - """.format(catalog_name, description) - - if client: - headers = {'Accept': 'application/*+xml;version=' + API_VERSION, - 'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']} - headers['Content-Type'] = 'application/vnd.vmware.vcloud.uploadVAppTemplateParams+xml' - - response = requests.post(url=catalog_href, - headers=headers, - data=data, - verify=False) - if response.status_code != 201: - self.logger.debug("Failed to create vApp template") - raise Exception("Failed to create vApp template") - - if response.status_code == requests.codes.created: - catalogItem = XmlElementTree.fromstring(response.content) - entity = [child for child in catalogItem if - child.get("type") == "application/vnd.vmware.vcloud.vAppTemplate+xml"][0] - href = entity.get('href') - template = href - - response = requests.get(url=href, - headers=headers, - verify=False) - if response.status_code == requests.codes.ok: - headers['Content-Type'] = 'Content-Type text/xml' - result = re.search('rel="upload:default"\shref="(.*?\/descriptor.ovf)"', response.content) - if result: - transfer_href = result.group(1) - - response = requests.put(url=transfer_href, headers=headers, - data=open(media_file_name, 'rb'), - verify=False) - - if response.status_code != requests.codes.ok: - self.logger.debug( - "Failed create vApp template for catalog name {} and image {}".format( - catalog_name, - media_file_name)) - return False - - # TODO fix this with aync block - time.sleep(5) - - self.logger.debug("vApp template for catalog name {} and image {}".format( - catalog_name, - media_file_name)) - - # uploading VMDK file - # check status of OVF upload and upload remaining files. - - response = requests.get(url=template, - headers=headers, - verify=False) - - if response.status_code == requests.codes.ok: - result = re.search('rel="upload:default"\s*href="(.*?vmdk)"', response.content) - if result: - link_href = result.group(1) - # we skip ovf since it already uploaded. - if 'ovf' in link_href: - continue - # The OVF file and VMDK must be in a same directory - head, _ = os.path.split(media_file_name) - file_vmdk = head + '/' + link_href.split("/")[-1] - if not os.path.isfile(file_vmdk): - return False - statinfo = os.stat(file_vmdk) - if statinfo.st_size == 0: - return False - hrefvmdk = link_href - if progress: - widgets = ['Uploading file: ', Percentage(), ' ', Bar(), ' ', ETA(), ' ', - FileTransferSpeed()] - progress_bar = ProgressBar(widgets=widgets, maxval=statinfo.st_size).start() - - bytes_transferred = 0 - f = open(file_vmdk, 'rb') - while bytes_transferred < statinfo.st_size: - my_bytes = f.read(chunk_bytes) - if len(my_bytes) <= chunk_bytes: - headers['Content-Range'] = 'bytes %s-%s/%s' % ( - bytes_transferred, len(my_bytes) - 1, statinfo.st_size) - headers['Content-Length'] = str(len(my_bytes)) - response = requests.put(url=hrefvmdk, - headers=headers, - data=my_bytes, - verify=False) - if response.status_code == requests.codes.ok: - bytes_transferred += len(my_bytes) - if progress: - progress_bar.update(bytes_transferred) - else: - self.logger.debug( - 'file upload failed with error: [%s] %s' % (response.status_code, - response.content)) - - f.close() - return False - f.close() - if progress: - progress_bar.finish() - time.sleep(60) - return True - else: - self.logger.debug("Failed retrieve vApp template for catalog name {} for OVF {}". - format(catalog_name, media_file_name)) - return False - except Exception as exp: - self.logger.debug("Failed while uploading OVF to catalog {} for OVF file {} with Exception {}" - .format(catalog_name, media_file_name, exp)) - raise Exception( - "Failed while uploading OVF to catalog {} for OVF file {} with Exception {}" - .format(catalog_name, media_file_name, exp)) - self.logger.debug("Failed to retrieve catalog name {} for OVF file {}".format(catalog_name, media_file_name)) - return False - - -if __name__ == "__main__": - - print("This file is deprecated. Please use ovf_uplader_cli instead.") - - # vmware vcloud director credentials - vcd_hostname = sys.argv[1] - vcd_username = sys.argv[2] - vcd_password = sys.argv[3] - orgname = sys.argv[4] - # OVF image path to be upload to vCD - ovf_file_path = sys.argv[5] - - logging.basicConfig(filename='ovf_upload.log', level=logging.DEBUG) - logger = logging.getLogger(__name__) - - obj = vCloudconfig(vcd_hostname, vcd_username, vcd_password, orgname, logger) - - dirpath, filename = os.path.split(ovf_file_path) - filename_name, file_extension = os.path.splitext(filename) - - # Get image name from cirros vnfd - cirros_yaml = '../descriptor-packages/vnfd/cirros_vnf/src/cirros_vnfd.yaml' - rh = open(cirros_yaml, 'r') - match = re.search("image:\s'(.*?)'\n", rh.read()) - if match: - catalog = match.group(1) - - if file_extension == '.ovf': - obj.get_catalog_id_from_path(catalog_name=catalog, path=ovf_file_path, - progress=True)