X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=RO-VIM-vmware%2Fosm_rovim_vmware%2Fvimconn_vmware.py;h=55c1f2bfff4a9d4cfb65604c3d1ca566fb6909b4;hb=3b1d48d0bc01ea98060d923ccd4dae33480df027;hp=db121e8803b75aefa41cd0e2e402408a1124e561;hpb=1b8560079e444a0c98ad2083fa66615c4b6a20fd;p=osm%2FRO.git diff --git a/RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py b/RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py index db121e88..55c1f2bf 100644 --- a/RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py +++ b/RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- ## -# Copyright 2016-2017 VMware Inc. +# Copyright 2016-2019 VMware Inc. # This file is part of ETSI OSM # All Rights Reserved. # @@ -33,7 +33,6 @@ import shutil import subprocess import tempfile import traceback -import itertools import requests import ssl import atexit @@ -117,6 +116,7 @@ netStatus2manoFormat = {'ACTIVE': 'ACTIVE', 'PAUSED': 'PAUSED', 'INACTIVE': 'INA 'ERROR': 'ERROR', 'DELETED': 'DELETED' } + class vimconnector(vimconn.vimconnector): # dict used to store flavor in memory flavorlist = {} @@ -305,12 +305,11 @@ class vimconnector(vimconn.vimconnector): try: host = self.url org = 'System' - client_as_admin = Client(host, verify_ssl_certs=False) - client_as_admin.set_highest_supported_version() + client_as_admin = Client(host, verify_ssl_certs=False, api_version=API_VERSION) client_as_admin.set_credentials(BasicLoginCredentials(self.admin_user, org, self.admin_password)) except Exception as e: raise vimconn.vimconnException( - "Can't connect to a vCloud director as: {} with exception {}".format(self.admin_user, e)) + "Can't connect to vCloud director as: {} with exception {}".format(self.admin_user, e)) return client_as_admin @@ -322,15 +321,16 @@ class vimconnector(vimconn.vimconnector): """ try: self.logger.debug("Logging into vCD {} as {} to datacenter {}.".format(self.org_name, - self.user, - self.org_name)) + self.user, + self.org_name)) host = self.url - client = Client(host, verify_ssl_certs=False) - client.set_highest_supported_version() + client = Client(host, verify_ssl_certs=False, api_version=API_VERSION) client.set_credentials(BasicLoginCredentials(self.user, self.org_name, self.passwd)) - except: - raise vimconn.vimconnConnectionException("Can't connect to a vCloud director org: " - "{} as user: {}".format(self.org_name, self.user)) + except Exception as e: + raise vimconn.vimconnConnectionException("Can't connect to vCloud director org: " + "{} as user {} with exception: {}".format(self.org_name, + self.user, + e)) return client @@ -389,8 +389,8 @@ class vimconnector(vimconn.vimconnector): else: raise vimconn.vimconnException("Tenant id indicated but not present in vcloud director") self.logger.debug("Setting organization uuid {}".format(self.org_uuid)) - except: - self.logger.debug("Failed initialize organization UUID for org {}".format(self.org_name)) + except Exception as e: + self.logger.debug("Failed initialize organization UUID for org {}: {}".format(self.org_name), e) self.logger.debug(traceback.format_exc()) self.org_uuid = None @@ -501,7 +501,7 @@ class vimconnector(vimconn.vimconnector): return vdclist - def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None): + def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None): """Adds a tenant network to VIM Params: 'net_name': name of the network @@ -518,7 +518,7 @@ class vimconnector(vimconn.vimconnector): 'dhcp_start_address': ip_schema, first IP to grant 'dhcp_count': number of IPs to grant. 'shared': if this network can be seen/use by other tenants/organization - 'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network + 'provider_network_profile': (optional) contains {segmentation-id: vlan, provider-network: vim_netowrk} Returns a tuple with the network identifier and created_items, or raises an exception on error created_items can be None or a dictionary where this method can include key-values that will be passed to the method delete_network. Can be used to store created segments, created l2gw connections, etc. @@ -526,8 +526,11 @@ class vimconnector(vimconn.vimconnector): as not present. """ - self.logger.debug("new_network tenant {} net_type {} ip_profile {} shared {}" - .format(net_name, net_type, ip_profile, shared)) + self.logger.debug("new_network tenant {} net_type {} ip_profile {} shared {} provider_network_profile {}" + .format(net_name, net_type, ip_profile, shared, provider_network_profile)) + vlan = None + if provider_network_profile: + vlan = provider_network_profile.get("segmentation-id") created_items = {} isshared = 'false' @@ -539,9 +542,16 @@ class vimconnector(vimconn.vimconnector): # if self.config.get('dv_switch_name') == None: # raise vimconn.vimconnConflictException("You must provide 'dv_switch_name' at config value") # network_uuid = self.create_dvPort_group(net_name) + parent_network_uuid = None + + if provider_network_profile is not None: + for k, v in provider_network_profile.items(): + if k == 'physical_network': + parent_network_uuid = self.get_physical_network_by_name(v) network_uuid = self.create_network(network_name=net_name, net_type=net_type, - ip_profile=ip_profile, isshared=isshared) + ip_profile=ip_profile, isshared=isshared, + parent_network_uuid=parent_network_uuid) if network_uuid is not None: return network_uuid, created_items else: @@ -574,7 +584,7 @@ class vimconnector(vimconn.vimconnector): self.logger.error("Failed to get vdc content") raise vimconn.vimconnNotFoundException("Failed to get vdc content") else: - content = XmlElementTree.fromstring(response.content) + content = XmlElementTree.fromstring(response.text) network_list = [] try: @@ -589,7 +599,7 @@ class vimconnector(vimconn.vimconnector): self.logger.error("Failed to get network content") raise vimconn.vimconnNotFoundException("Failed to get network content") else: - net_details = XmlElementTree.fromstring(response.content) + net_details = XmlElementTree.fromstring(response.text) filter_dict = {} net_uuid = net_details.get('id').split(":") @@ -664,7 +674,7 @@ class vimconnector(vimconn.vimconnector): self.logger.error("Failed to get vdc content") raise vimconn.vimconnNotFoundException("Failed to get vdc content") else: - content = XmlElementTree.fromstring(response.content) + content = XmlElementTree.fromstring(response.text) network_list = [] for item in content: @@ -678,7 +688,7 @@ class vimconnector(vimconn.vimconnector): self.logger.error("Failed to get network content") raise vimconn.vimconnNotFoundException("Failed to get network content") else: - net_details = XmlElementTree.fromstring(response.content) + net_details = XmlElementTree.fromstring(response.text) filter_entry = {} net_uuid = net_details.get('id').split(":") @@ -743,7 +753,7 @@ class vimconnector(vimconn.vimconnector): self.logger.error("Failed to get vdc content") raise vimconn.vimconnNotFoundException("Failed to get vdc content") else: - content = XmlElementTree.fromstring(response.content) + content = XmlElementTree.fromstring(response.text) filter_dict = {} @@ -758,7 +768,7 @@ class vimconnector(vimconn.vimconnector): self.logger.error("Failed to get network content") raise vimconn.vimconnNotFoundException("Failed to get network content") else: - net_details = XmlElementTree.fromstring(response.content) + net_details = XmlElementTree.fromstring(response.text) vdc_network_id = net_details.get('id').split(":") if len(vdc_network_id) == 4 and vdc_network_id[3] == net_id: @@ -960,55 +970,55 @@ class vimconnector(vimconn.vimconnector): url_list = [self.url, '/api/catalog/', image_id] catalog_herf = ''.join(url_list) - headers = {'Accept':'application/*+xml;version=' + API_VERSION, - 'x-vcloud-authorization': conn._session.headers['x-vcloud-authorization']} + headers = {'Accept': 'application/*+xml;version=' + API_VERSION, + 'x-vcloud-authorization': conn._session.headers['x-vcloud-authorization']} response = self.perform_request(req_type='GET', url=catalog_herf, headers=headers) if response.status_code != requests.codes.ok: - self.logger.debug("delete_image():GET REST API call {} failed. "\ + self.logger.debug("delete_image():GET REST API call {} failed. " "Return status code {}".format(catalog_herf, response.status_code)) raise vimconn.vimconnNotFoundException("Fail to get image {}".format(image_id)) lxmlroot_respond = lxmlElementTree.fromstring(response.content) namespaces = {prefix: uri for prefix, uri in lxmlroot_respond.nsmap.items() if prefix} - namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" + namespaces["xmlns"] = "http://www.vmware.com/vcloud/v1.5" - catalogItems_section = lxmlroot_respond.find("xmlns:CatalogItems",namespaces) - catalogItems = catalogItems_section.iterfind("xmlns:CatalogItem",namespaces) + catalogItems_section = lxmlroot_respond.find("xmlns:CatalogItems", namespaces) + catalogItems = catalogItems_section.iterfind("xmlns:CatalogItem", namespaces) for catalogItem in catalogItems: catalogItem_href = catalogItem.attrib['href'] response = self.perform_request(req_type='GET', - url=catalogItem_href, - headers=headers) + url=catalogItem_href, + headers=headers) if response.status_code != requests.codes.ok: - self.logger.debug("delete_image():GET REST API call {} failed. "\ + self.logger.debug("delete_image():GET REST API call {} failed. " "Return status code {}".format(catalog_herf, response.status_code)) raise vimconn.vimconnNotFoundException("Fail to get catalogItem {} for catalog {}".format( - catalogItem, - image_id)) + catalogItem, + image_id)) lxmlroot_respond = lxmlElementTree.fromstring(response.content) namespaces = {prefix: uri for prefix, uri in lxmlroot_respond.nsmap.items() if prefix} - namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" - catalogitem_remove_href = lxmlroot_respond.find("xmlns:Link[@rel='remove']",namespaces).attrib['href'] + namespaces["xmlns"] = "http://www.vmware.com/vcloud/v1.5" + catalogitem_remove_href = lxmlroot_respond.find("xmlns:Link[@rel='remove']", namespaces).attrib['href'] - #Remove catalogItem + # Remove catalogItem response = self.perform_request(req_type='DELETE', - url=catalogitem_remove_href, - headers=headers) + url=catalogitem_remove_href, + headers=headers) if response.status_code == requests.codes.no_content: self.logger.debug("Deleted Catalog item {}".format(catalogItem)) else: raise vimconn.vimconnException("Fail to delete Catalog Item {}".format(catalogItem)) - #Remove catalog + # Remove catalog url_list = [self.url, '/api/admin/catalog/', image_id] catalog_remove_herf = ''.join(url_list) response = self.perform_request(req_type='DELETE', @@ -1021,7 +1031,6 @@ class vimconnector(vimconn.vimconnector): else: raise vimconn.vimconnException("Fail to delete Catalog {}".format(image_id)) - def catalog_exists(self, catalog_name, catalogs): """ @@ -1098,7 +1107,7 @@ class vimconnector(vimconn.vimconnector): data=data) if response.status_code == requests.codes.created: - catalogItem = XmlElementTree.fromstring(response.content) + catalogItem = XmlElementTree.fromstring(response.text) entity = [child for child in catalogItem if child.get("type") == "application/vnd.vmware.vcloud.vAppTemplate+xml"][0] href = entity.get('href') @@ -1110,7 +1119,7 @@ class vimconnector(vimconn.vimconnector): 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) + result = re.search('rel="upload:default"\shref="(.*?\/descriptor.ovf)"', response.text) if result: transfer_href = result.group(1) @@ -1136,7 +1145,7 @@ class vimconnector(vimconn.vimconnector): headers=headers) if response.status_code == requests.codes.ok: - result = re.search('rel="upload:default"\s*href="(.*?vmdk)"',response.content) + result = re.search('rel="upload:default"\s*href="(.*?vmdk)"', response.text) if result: link_href = result.group(1) # we skip ovf since it already uploaded. @@ -1176,7 +1185,7 @@ class vimconnector(vimconn.vimconnector): else: self.logger.debug( 'file upload failed with error: [{}] {}'.format(response.status_code, - response.content)) + response.text)) f.close() return False @@ -1310,7 +1319,7 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnException("Wrong container. vCloud director supports only OVF.") catalog_name = os.path.splitext(filename)[0] - catalog_md5_name = hashlib.md5(path).hexdigest() + catalog_md5_name = hashlib.md5(path.encode('utf-8')).hexdigest() self.logger.debug("File name {} Catalog Name {} file path {} " "vdc catalog name {}".format(filename, catalog_name, path, catalog_md5_name)) @@ -1460,8 +1469,8 @@ class vimconnector(vimconn.vimconnector): if response.status_code == 403: response = self.retry_rest('GET', vapp_call) - tree = XmlElementTree.fromstring(response.content) - return tree.attrib['name'] + tree = XmlElementTree.fromstring(response.text) + return tree.attrib['name'] if 'name' in tree.attrib else None except Exception as e: self.logger.exception(e) return None @@ -1595,7 +1604,7 @@ class vimconnector(vimconn.vimconnector): # client must provide at least one entry in net_list if not we report error #If net type is mgmt, then configure it as primary net & use its NIC index as primary NIC - #If no mgmt, then the 1st NN in netlist is considered as primary net. + # If no mgmt, then the 1st NN in netlist is considered as primary net. primary_net = None primary_netname = None primary_net_href = None @@ -1610,7 +1619,7 @@ class vimconnector(vimconn.vimconnector): try: primary_net_id = primary_net['net_id'] url_list = [self.url, '/api/network/', primary_net_id] - primary_net_href = ''.join(url_list) + primary_net_href = ''.join(url_list) network_dict = self.get_vcd_network(network_uuid=primary_net_id) if 'name' in network_dict: primary_netname = network_dict['name'] @@ -1627,7 +1636,7 @@ class vimconnector(vimconn.vimconnector): if not vdc_obj: raise vimconn.vimconnNotFoundException("new_vminstance(): Failed to get VDC object") - for retry in (1,2): + for retry in (1, 2): items = org.get_catalog_item(catalog_hash_name, catalog_hash_name) catalog_items = [items.attrib] @@ -1639,7 +1648,7 @@ class vimconnector(vimconn.vimconnector): response = self.perform_request(req_type='GET', url=catalog_items[0].get('href'), headers=headers) - catalogItem = XmlElementTree.fromstring(response.content) + catalogItem = XmlElementTree.fromstring(response.text) entity = [child for child in catalogItem if child.get("type") == "application/vnd.vmware.vcloud.vAppTemplate+xml"][0] vapp_tempalte_href = entity.get("href") @@ -1650,9 +1659,9 @@ class vimconnector(vimconn.vimconnector): self.logger.debug("REST API call {} failed. Return status code {}".format(vapp_tempalte_href, response.status_code)) else: - result = (response.content).replace("\n"," ") + result = (response.text).replace("\n", " ") - vapp_template_tree = XmlElementTree.fromstring(response.content) + vapp_template_tree = XmlElementTree.fromstring(response.text) children_element = [child for child in vapp_template_tree if 'Children' in child.tag][0] vm_element = [child for child in children_element if 'Vm' in child.tag][0] vm_name = vm_element.get('name') @@ -1667,85 +1676,20 @@ class vimconnector(vimconn.vimconnector): vdc_id = vdc.get('id').split(':')[-1] instantiate_vapp_href = "{}/api/vdc/{}/action/instantiateVAppTemplate".format(self.url, vdc_id) - data = """ - - Vapp instantiation - - - Configuration parameters for logical networks - - - - bridged - - - - - Lease Settings - 172800 - 2014-04-25T08:08:16.438-07:00 - - - - - - - false - - - - Specifies the available VM network connections - - 0 - true - DHCP - - - Virtual hardware requirements - - hertz * 10^6 - Number of Virtual CPUs - {cpu} virtual CPU(s) - 4 - 0 - 3 - {cpu} - 0 - {core} - - byte * 2^20 - Memory Size - {memory} MB of memory - 5 - 0 - 4 - {memory} - 0 - - - - - false - """.format(vmname_andid, - primary_netname, - primary_net_href, - vapp_tempalte_href, - vm_href, - vm_id, - vm_name, - primary_netname, - cpu=cpus, - core=cores, - memory=memory_mb) + with open(os.path.join(os.path.dirname(__file__), 'InstantiateVAppTemplateParams.xml'), 'r') as f: + template = f.read() + + data = template.format(vmname_andid, + primary_netname, + primary_net_href, + vapp_tempalte_href, + vm_href, + vm_id, + vm_name, + primary_netname, + cpu=vm_cpus, + core=1, + memory=vm_memory) response = self.perform_request(req_type='POST', url=instantiate_vapp_href, @@ -1755,12 +1699,12 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 201: self.logger.error("REST call {} failed reason : {}"\ "status code : {}".format(instantiate_vapp_href, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("new_vminstance(): Failed to create"\ "vAapp {}".format(vmname_andid)) else: - vapptask = self.get_task_from_response(response.content) + vapptask = self.get_task_from_response(response.text) if vapptask is None and retry==1: self.get_token() # Retry getting token @@ -1794,16 +1738,14 @@ class vimconnector(vimconn.vimconnector): except Exception as exp: raise vimconn.vimconnUnexpectedResponse( - "new_vminstance(): Failed to retrieve vApp {} after creation: Exception:{}" - .format(vmname_andid, exp)) + "new_vminstance(): Failed to retrieve vApp {} after creation: Exception:{}" + .format(vmname_andid, exp)) if vapp_uuid is None: raise vimconn.vimconnUnexpectedResponse( - "new_vminstance(): Failed to retrieve vApp {} after creation".format( - vmname_andid)) + "new_vminstance(): Failed to retrieve vApp {} after creation".format(vmname_andid)) - #Add PCI passthrough/SRIOV configrations - vm_obj = None + # Add PCI passthrough/SRIOV configrations pci_devices_info = [] reserve_memory = False @@ -1813,30 +1755,30 @@ class vimconnector(vimconn.vimconnector): elif (net["type"] == "VF" or net["type"] == "SR-IOV" or net["type"] == "VFnotShared") and 'net_id'in net: reserve_memory = True - #Add PCI + # Add PCI if len(pci_devices_info) > 0: self.logger.info("Need to add PCI devices {} into VM {}".format(pci_devices_info, - vmname_andid )) - PCI_devices_status, vm_obj, vcenter_conect = self.add_pci_devices(vapp_uuid, - pci_devices_info, - vmname_andid) - if PCI_devices_status: - self.logger.info("Added PCI devives {} to VM {}".format( + vmname_andid)) + PCI_devices_status, _, _ = self.add_pci_devices(vapp_uuid, pci_devices_info, vmname_andid) - ) + if PCI_devices_status: + self.logger.info("Added PCI devives {} to VM {}".format( + pci_devices_info, + vmname_andid)) reserve_memory = True else: self.logger.info("Fail to add PCI devives {} to VM {}".format( - pci_devices_info, - vmname_andid) - ) + pci_devices_info, + vmname_andid)) + + # Add serial console - this allows cloud images to boot as if we are running under OpenStack + self.add_serial_device(vapp_uuid) - # Modify vm disk if vm_disk: - #Assuming there is only one disk in ovf and fast provisioning in organization vDC is disabled + # Assuming there is only one disk in ovf and fast provisioning in organization vDC is disabled result = self.modify_vm_disk(vapp_uuid, vm_disk) - if result : + if result: self.logger.debug("Modified Disk size of VM {} ".format(vmname_andid)) #Add new or existing disks to vApp @@ -1976,8 +1918,6 @@ class vimconnector(vimconn.vimconnector): self.upload_iso_to_catalog(config_drive_catalog_id, iso_path) # Attach the config-drive ISO to the VM self.logger.info('new_vminstance(): Attaching the config-drive ISO to the VM') - # The ISO remains in INVALID_STATE right after the PUT request (its a blocking call though) - time.sleep(5) self.insert_media_to_vm(vapp, config_drive_catalog_id) shutil.rmtree(os.path.dirname(iso_path), ignore_errors=True) @@ -2006,7 +1946,6 @@ class vimconnector(vimconn.vimconnector): .format(name, exp)) raise vimconn.vimconnException("new_vminstance(): Failed create new vm instance {} with exception {}" .format(name, exp)) - # check if vApp deployed and if that the case return vApp UUID otherwise -1 wait_time = 0 vapp_uuid = None @@ -2172,7 +2111,7 @@ class vimconnector(vimconn.vimconnector): self.logger.error(error_msg) raise Exception(error_msg) - catalogItem = XmlElementTree.fromstring(response.content) + catalogItem = XmlElementTree.fromstring(response.text) entity = [child for child in catalogItem if child.get("type") == "application/vnd.vmware.vcloud.media+xml"][0] entity_href = entity.get('href') @@ -2185,7 +2124,7 @@ class vimconnector(vimconn.vimconnector): media_upload_href = match.group(1) else: raise Exception('Could not parse the upload URL for the media file from the last response') - upload_iso_task = self.get_task_from_response(response.content) + upload_iso_task = self.get_task_from_response(response.text) headers['Content-Type'] = 'application/octet-stream' response = self.perform_request(req_type='PUT', url=media_upload_href, @@ -2572,7 +2511,7 @@ class vimconnector(vimconn.vimconnector): self.logger.debug ("REST API call {} failed. Return status code {}"\ .format(url, response.status_code)) else: - xmlroot_response = XmlElementTree.fromstring(response.content) + xmlroot_response = XmlElementTree.fromstring(response.text) for child in xmlroot_response: if 'ProviderVdcReference' in child.tag: pvdc_href = child.attrib.get('href') @@ -2712,7 +2651,7 @@ class vimconnector(vimconn.vimconnector): self.logger.debug("Client requesting delete vm instance {} ".format(vm__vim_uuid)) - org, vdc = self.get_vdc_details() + _, vdc = self.get_vdc_details() vdc_obj = VDC(self.client, href=vdc.get('href')) if vdc_obj is None: self.logger.debug("delete_vminstance(): Failed to get a reference of VDC for a tenant {}".format( @@ -2734,7 +2673,7 @@ class vimconnector(vimconn.vimconnector): if vapp: if vapp_resource.get('deployed') == 'true': self.logger.info("Powering off vApp {}".format(vapp_name)) - #Power off vApp + # Power off vApp powered_off = False wait_time = 0 while wait_time <= MAX_WAIT_TIME: @@ -2748,20 +2687,22 @@ class vimconnector(vimconn.vimconnector): self.logger.info("Wait for vApp {} to power off".format(vapp_name)) time.sleep(INTERVAL_TIME) - wait_time +=INTERVAL_TIME + wait_time += INTERVAL_TIME if not powered_off: - self.logger.debug("delete_vminstance(): Failed to power off VM instance {} ".format(vm__vim_uuid)) + self.logger.debug( + "delete_vminstance(): Failed to power off VM instance {} ".format(vm__vim_uuid)) else: self.logger.info("delete_vminstance(): Powered off VM instance {} ".format(vm__vim_uuid)) - #Undeploy vApp + # Undeploy vApp self.logger.info("Undeploy vApp {}".format(vapp_name)) wait_time = 0 undeployed = False while wait_time <= MAX_WAIT_TIME: vapp = VApp(self.client, resource=vapp_resource) if not vapp: - self.logger.debug("delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid)) + self.logger.debug( + "delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid)) return -1, "delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid) undeploy_task = vapp.undeploy() @@ -2773,7 +2714,7 @@ class vimconnector(vimconn.vimconnector): self.logger.debug("Wait for vApp {} to undeploy".format(vapp_name)) time.sleep(INTERVAL_TIME) - wait_time +=INTERVAL_TIME + wait_time += INTERVAL_TIME if not undeployed: self.logger.debug("delete_vminstance(): Failed to undeploy vApp {} ".format(vm__vim_uuid)) @@ -2788,7 +2729,8 @@ class vimconnector(vimconn.vimconnector): while wait_time <= MAX_WAIT_TIME: vapp = VApp(self.client, resource=vapp_resource) if not vapp: - self.logger.debug("delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid)) + self.logger.debug( + "delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid)) return -1, "delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid) delete_task = vdc_obj.delete_vapp(vapp.name, force=True) @@ -2800,7 +2742,7 @@ class vimconnector(vimconn.vimconnector): self.logger.debug("Wait for vApp {} to delete".format(vapp_name)) time.sleep(INTERVAL_TIME) - wait_time +=INTERVAL_TIME + wait_time += INTERVAL_TIME if result is None: self.logger.debug("delete_vminstance(): Failed delete uuid {} ".format(vm__vim_uuid)) @@ -2818,11 +2760,10 @@ class vimconnector(vimconn.vimconnector): 'vapp_name"{}". Deleting it.'.format(config_drive_catalog_id, vapp_name)) self.delete_image(config_drive_catalog_id) return vm__vim_uuid - except: + except Exception: self.logger.debug(traceback.format_exc()) raise vimconn.vimconnException("delete_vminstance(): Failed delete vm instance {}".format(vm__vim_uuid)) - def refresh_vms_status(self, vm_list): """Get the status of the virtual machines and their interfaces/ports Params: the list of VM identifiers @@ -2876,14 +2817,13 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 200: self.logger.error("refresh_vms_status : REST call {} failed reason : {}"\ "status code : {}".format(vm.get('href'), - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("refresh_vms_status : Failed to get "\ "VM details") - xmlroot = XmlElementTree.fromstring(response.content) + xmlroot = XmlElementTree.fromstring(response.text) - - result = response.content.replace("\n"," ") + result = response.text.replace("\n", " ") hdd_match = re.search('vcloud:capacity="(\d+)"\svcloud:storageProfileOverrideVmDefault=',result) if hdd_match: hdd_mb = hdd_match.group(1) @@ -3151,13 +3091,13 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 200: self.logger.error("REST call {} failed reason : {}"\ "status code : {}".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("get_vminstance_console : Failed to get "\ "VM Mks ticket details") - s = re.search("(.*?)",response.content) + s = re.search("(.*?)", response.text) console_dict['server'] = s.group(1) if s else None - s1 = re.search("(\d+)",response.content) + s1 = re.search("(\d+)", response.text) console_dict['port'] = s1.group(1) if s1 else None @@ -3175,11 +3115,11 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 200: self.logger.error("REST call {} failed reason : {}"\ "status code : {}".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("get_vminstance_console : Failed to get "\ "VM console details") - s = re.search(">.*?/(vm-\d+.*).*?/(vm-\d+.*)= 2: dns2_text = "\n {}\n".format(dns_list[1]) - data = """ - Openmano created - - - - {1:s} - {2:s} - {3:s} - {4:s}{5:s} - {6:s} - - - {7:s} - {8:s} - - - - - {9:s} - - {10:s} - """.format(escape(network_name), is_inherited, gateway_address, - subnet_address, dns1, dns2_text, dhcp_enabled, - dhcp_start_address, dhcp_end_address, - fence_mode, isshared) + if net_type == "isolated": + fence_mode="isolated" + data = """ + Openmano created + + + + {1:s} + {2:s} + {3:s} + {4:s}{5:s} + {6:s} + + + {7:s} + {8:s} + + + + + {9:s} + + {10:s} + """.format(escape(network_name), is_inherited, gateway_address, + subnet_address, dns1, dns2_text, dhcp_enabled, + dhcp_start_address, dhcp_end_address, + fence_mode, isshared) + else: + fence_mode = "bridged" + data = """ + Openmano created + + + + {1:s} + {2:s} + {3:s} + {4:s}{5:s} + {6:s} + + + {7:s} + {8:s} + + + + + + {10:s} + + {11:s} + """.format(escape(network_name), is_inherited, gateway_address, + subnet_address, dns1, dns2_text, dhcp_enabled, + dhcp_start_address, dhcp_end_address, available_networks, + fence_mode, isshared) headers['Content-Type'] = 'application/vnd.vmware.vcloud.orgVdcNetwork+xml' try: @@ -3901,18 +3947,18 @@ class vimconnector(vimconn.vimconnector): data=data) if response.status_code != 201: - self.logger.debug("Create Network POST REST API call failed. Return status code {}, Response content: {}" - .format(response.status_code,response.content)) + self.logger.debug("Create Network POST REST API call failed. Return status code {}, response.text: {}" + .format(response.status_code, response.text)) else: - network_task = self.get_task_from_response(response.content) + network_task = self.get_task_from_response(response.text) self.logger.debug("Create Network REST : Waiting for Network creation complete") time.sleep(5) result = self.client.get_task_monitor().wait_for_success(task=network_task) if result.get('status') == 'success': - return response.content + return response.text else: self.logger.debug("create_network_rest task failed. Network Create response : {}" - .format(response.content)) + .format(response.text)) except Exception as exp: self.logger.debug("create_network_rest : Exception : {} ".format(exp)) @@ -3957,7 +4003,7 @@ class vimconnector(vimconn.vimconnector): headers=headers) if response.status_code == requests.codes.ok: - return response.content + return response.text return None def create_vdc(self, vdc_name=None): @@ -4009,7 +4055,7 @@ class vimconnector(vimconn.vimconnector): # container url to a template vdc_template_ref = None try: - vm_list_xmlroot = XmlElementTree.fromstring(response.content) + vm_list_xmlroot = XmlElementTree.fromstring(response.text) for child in vm_list_xmlroot: # application/vnd.vmware.admin.providervdc+xml # we need find a template from witch we instantiate VDC @@ -4018,7 +4064,7 @@ class vimconnector(vimconn.vimconnector): vdc_template_ref = child.attrib.get('href') except: self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call)) - self.logger.debug("Respond body {}".format(response.content)) + self.logger.debug("Respond body {}".format(response.text)) return None # if we didn't found required pre defined template we return None @@ -4041,16 +4087,16 @@ class vimconnector(vimconn.vimconnector): headers=headers, data=data) - vdc_task = self.get_task_from_response(response.content) + vdc_task = self.get_task_from_response(response.text) self.client.get_task_monitor().wait_for_success(task=vdc_task) # if we all ok we respond with content otherwise by default None if response.status_code >= 200 and response.status_code < 300: - return response.content + return response.text return None except: self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call)) - self.logger.debug("Respond body {}".format(response.content)) + self.logger.debug("Respond body {}".format(response.text)) return None @@ -4092,7 +4138,7 @@ class vimconnector(vimconn.vimconnector): return None else: try: - vm_list_xmlroot = XmlElementTree.fromstring(response.content) + vm_list_xmlroot = XmlElementTree.fromstring(response.text) for child in vm_list_xmlroot: # application/vnd.vmware.admin.providervdc+xml if child.tag.split("}")[1] == 'Link': @@ -4101,7 +4147,7 @@ class vimconnector(vimconn.vimconnector): add_vdc_rest_url = child.attrib.get('href') except: self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call)) - self.logger.debug("Respond body {}".format(response.content)) + self.logger.debug("Respond body {}".format(response.text)) return None response = self.get_provider_rest(vca=vca) @@ -4139,7 +4185,7 @@ class vimconnector(vimconn.vimconnector): # if we all ok we respond with content otherwise by default None if response.status_code == 201: - return response.content + return response.text return None def get_vapp_details_rest(self, vapp_uuid=None, need_admin_access=False): @@ -4186,7 +4232,7 @@ class vimconnector(vimconn.vimconnector): return parsed_respond try: - xmlroot_respond = XmlElementTree.fromstring(response.content) + xmlroot_respond = XmlElementTree.fromstring(response.text) parsed_respond['ovfDescriptorUploaded'] = xmlroot_respond.attrib['ovfDescriptorUploaded'] namespaces = {"vssd":"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" , @@ -4303,7 +4349,7 @@ class vimconnector(vimconn.vimconnector): response = self.retry_rest('POST', console_rest_call) if response.status_code == requests.codes.ok: - return response.content + return response.text return None @@ -4404,7 +4450,7 @@ class vimconnector(vimconn.vimconnector): self.logger.debug("PUT REST API call {} failed. Return status code {}".format(disk_href, response.status_code)) else: - modify_disk_task = self.get_task_from_response(response.content) + modify_disk_task = self.get_task_from_response(response.text) result = self.client.get_task_monitor().wait_for_success(task=modify_disk_task) if result.get('status') == 'success': return True @@ -4412,11 +4458,46 @@ class vimconnector(vimconn.vimconnector): return False return None - except Exception as exp : + except Exception as exp: self.logger.info("Error occurred calling rest api for modifing disk size {}".format(exp)) return None - def add_pci_devices(self, vapp_uuid , pci_devices , vmname_andid): + def add_serial_device(self, vapp_uuid): + """ + Method to attach a serial device to a VM + + Args: + vapp_uuid - uuid of vApp/VM + + Returns: + """ + self.logger.info("Add serial devices into vApp {}".format(vapp_uuid)) + _, content = self.get_vcenter_content() + vm_moref_id = self.get_vm_moref_id(vapp_uuid) + if vm_moref_id: + try: + host_obj, vm_obj = self.get_vm_obj(content, vm_moref_id) + self.logger.info("VM {} is currently on host {}".format(vm_obj, host_obj)) + if host_obj and vm_obj: + spec = vim.vm.ConfigSpec() + spec.deviceChange = [] + serial_spec = vim.vm.device.VirtualDeviceSpec() + serial_spec.operation = 'add' + serial_port = vim.vm.device.VirtualSerialPort() + serial_port.yieldOnPoll = True + backing = serial_port.URIBackingInfo() + backing.serviceURI = 'tcp://:65500' + backing.direction = 'server' + serial_port.backing = backing + serial_spec.device = serial_port + spec.deviceChange.append(serial_spec) + vm_obj.ReconfigVM_Task(spec=spec) + + self.logger.info("Adding serial device to VM {}".format(vm_obj)) + except vmodl.MethodFault as error: + self.logger.error("Error occurred while adding PCI devices {} ", error) + + def add_pci_devices(self, vapp_uuid, pci_devices, vmname_andid): """ Method to attach pci devices to VM @@ -4429,7 +4510,7 @@ class vimconnector(vimconn.vimconnector): vcenter_conect object """ vm_obj = None - self.logger.info("Add pci devices {} into vApp {}".format(pci_devices , vapp_uuid)) + self.logger.info("Add pci devices {} into vApp {}".format(pci_devices, vapp_uuid)) vcenter_conect, content = self.get_vcenter_content() vm_moref_id = self.get_vm_moref_id(vapp_uuid) @@ -4568,12 +4649,12 @@ class vimconnector(vimconn.vimconnector): if len(avalible_devices) < need_devices: self.logger.debug("Host {} don't have {} number of active devices".format(host, need_devices)) - self.logger.debug("found only {} devives {}".format(len(avalible_devices), + self.logger.debug("found only {} devices {}".format(len(avalible_devices), avalible_devices)) return None else: required_devices = avalible_devices[:need_devices] - self.logger.info("Found {} PCI devivces on host {} but required only {}".format( + self.logger.info("Found {} PCI devices on host {} but required only {}".format( len(avalible_devices), host, need_devices)) @@ -4811,12 +4892,12 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 200: self.logger.error("REST call {} failed reason : {}"\ "status code : {}".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("reserve_memory_for_all_vms : Failed to get "\ "memory") - bytexml = bytes(bytearray(response.content, encoding='utf-8')) + bytexml = bytes(bytearray(response.text, encoding='utf-8')) contentelem = lxmlElementTree.XML(bytexml) namespaces = {prefix:uri for prefix,uri in contentelem.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" @@ -4840,12 +4921,12 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 202: self.logger.error("REST call {} failed reason : {}"\ "status code : {} ".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("reserve_memory_for_all_vms : Failed to update "\ "virtual hardware memory section") else: - mem_task = self.get_task_from_response(response.content) + mem_task = self.get_task_from_response(response.text) result = self.client.get_task_monitor().wait_for_success(task=mem_task) if result.get('status') == 'success': self.logger.info("reserve_memory_for_all_vms(): VM {} succeeded "\ @@ -4880,12 +4961,12 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 200: self.logger.error("REST call {} failed reason : {}"\ "status code : {}".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("connect_vapp_to_org_vdc_network : Failed to get "\ "network config section") - data = response.content + data = response.text headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConfigSection+xml' net_id = self.get_network_id_by_name(net_name) if not net_id: @@ -4932,12 +5013,12 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 202: self.logger.error("REST call {} failed reason : {}"\ "status code : {} ".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("connect_vapp_to_org_vdc_network : Failed to update "\ "network config section") else: - vapp_task = self.get_task_from_response(response.content) + vapp_task = self.get_task_from_response(response.text) result = self.client.get_task_monitor().wait_for_success(task=vapp_task) if result.get('status') == 'success': self.logger.info("connect_vapp_to_org_vdc_network(): Vapp {} connected to "\ @@ -4973,12 +5054,12 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 200: self.logger.error("REST call {} failed reason : {}"\ "status code : {}".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("remove_primary_network_adapter : Failed to get "\ "network connection section") - data = response.content + data = response.text data = data.split('' not in data: self.logger.debug("add_network_adapter PrimaryNIC not in data") @@ -5133,12 +5214,12 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 202: self.logger.error("REST call {} failed reason : {}"\ "status code : {} ".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to update "\ "network connection section") else: - nic_task = self.get_task_from_response(response.content) + nic_task = self.get_task_from_response(response.text) result = self.client.get_task_monitor().wait_for_success(task=nic_task) if result.get('status') == 'success': self.logger.info("add_network_adapter_to_vms(): VM {} conneced to "\ @@ -5164,11 +5245,11 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 200: self.logger.error("REST call {} failed reason : {}"\ "status code : {}".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to get "\ "network connection section") - data = response.content + data = response.text data = data.split('17 """.format(disk_size_mb, bus_subtype, bus_type, instance_id) - new_data = response.content + new_data = response.text #Add new item at the bottom new_data = new_data.replace('\n', '\n{}\n'.format(new_item)) @@ -5555,10 +5636,10 @@ class vimconnector(vimconn.vimconnector): response = self.retry_rest('PUT', disk_href, add_headers, new_data) if response.status_code != 202: - self.logger.error("PUT REST API call {} failed. Return status code {}. Response Content:{}" - .format(disk_href, response.status_code, response.content)) + self.logger.error("PUT REST API call {} failed. Return status code {}. response.text:{}" + .format(disk_href, response.status_code, response.text)) else: - add_disk_task = self.get_task_from_response(response.content) + add_disk_task = self.get_task_from_response(response.text) result = self.client.get_task_monitor().wait_for_success(task=add_disk_task) if result.get('status') == 'success': status = True @@ -5798,7 +5879,7 @@ class vimconnector(vimconn.vimconnector): response = self.perform_request(req_type='GET', url=catalog_items[0].get('href'), headers=headers) - catalogItem = XmlElementTree.fromstring(response.content) + catalogItem = XmlElementTree.fromstring(response.text) entity = [child for child in catalogItem if child.get("type") == "application/vnd.vmware.vcloud.vAppTemplate+xml"][0] vapp_tempalte_href = entity.get("href") #get vapp details and parse moref id @@ -5822,7 +5903,7 @@ class vimconnector(vimconn.vimconnector): vapp_tempalte_href, response.status_code)) else: - xmlroot_respond = XmlElementTree.fromstring(response.content) + xmlroot_respond = XmlElementTree.fromstring(response.text) children_section = xmlroot_respond.find('vm:Children/', namespaces) if children_section is not None: vCloud_extension_section = children_section.find('xmlns:VCloudExtension', namespaces) @@ -6299,23 +6380,23 @@ class vimconnector(vimconn.vimconnector): if response.status_code != 200: self.logger.error("REST call {} failed reason : {}"\ "status code : {}".format(url_rest_call, - response.content, + response.text, response.status_code)) raise vimconn.vimconnException("insert_media_to_vm(): Failed to get "\ "catalog details") # searching iso name and id - iso_name,media_id = self.get_media_details(vca, response.content) + iso_name, media_id = self.get_media_details(vca, response.text) if iso_name and media_id: data ="""