X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_ro%2Fvimconn_vmware.py;h=d4b83e5486399bf28219aaf9e8c8ae49a4f0025d;hb=ae5f52ca92fe953fd7b7448f945bf12eb2d62afc;hp=c65482bcd70ff6b58efa31806d03ab6fe5298ca3;hpb=b7ff355a95cf7ce07874aa5dc1d4267541277778;p=osm%2FRO.git diff --git a/osm_ro/vimconn_vmware.py b/osm_ro/vimconn_vmware.py index c65482bc..d4b83e54 100644 --- a/osm_ro/vimconn_vmware.py +++ b/osm_ro/vimconn_vmware.py @@ -76,7 +76,7 @@ DEFAULT_IP_PROFILE = {'dhcp_count':50, INTERVAL_TIME = 5 MAX_WAIT_TIME = 1800 -API_VERSION = '5.9' +API_VERSION = '31.0' __author__ = "Mustafa Bayramov, Arpita Kate, Sachin Bhangare, Prakash Kasar" __date__ = "$09-Mar-2018 11:09:29$" @@ -297,13 +297,13 @@ class vimconnector(vimconn.vimconnector): Returns: The return client object that latter can be used to connect to vcloud director as admin for provider vdc """ - self.logger.debug("Logging into vCD {} as admin.".format(self.org_name)) 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.set_credentials(BasicLoginCredentials(self.admin_user, org, self.admin_password)) except Exception as e: raise vimconn.vimconnException( @@ -317,13 +317,13 @@ class vimconnector(vimconn.vimconnector): Returns: The return client object that latter can be used to connect to vCloud director as admin for VDC """ - try: self.logger.debug("Logging into vCD {} as {} to datacenter {}.".format(self.org_name, self.user, self.org_name)) host = self.url client = Client(host, verify_ssl_certs=False) + client.set_highest_supported_version() client.set_credentials(BasicLoginCredentials(self.user, self.org_name, self.passwd)) except: raise vimconn.vimconnConnectionException("Can't connect to a vCloud director org: " @@ -500,17 +500,35 @@ class vimconnector(vimconn.vimconnector): return vdclist - def new_network(self, net_name, net_type, ip_profile=None, shared=False): + def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None): """Adds a tenant network to VIM - net_name is the name - net_type can be 'bridge','data'.'ptp'. - ip_profile is a dict containing the IP parameters of the network - shared is a boolean - Returns the network identifier""" + Params: + 'net_name': name of the network + 'net_type': one of: + 'bridge': overlay isolated network + 'data': underlay E-LAN network for Passthrough and SRIOV interfaces + 'ptp': underlay E-LINE network for Passthrough and SRIOV interfaces. + 'ip_profile': is a dict containing the IP parameters of the network + 'ip_version': can be "IPv4" or "IPv6" (Currently only IPv4 is implemented) + 'subnet_address': ip_prefix_schema, that is X.X.X.X/Y + 'gateway_address': (Optional) ip_schema, that is X.X.X.X + 'dns_address': (Optional) comma separated list of ip_schema, e.g. X.X.X.X[,X,X,X,X] + 'dhcp_enabled': True or False + '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 + 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. + Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same + as not present. + """ self.logger.debug("new_network tenant {} net_type {} ip_profile {} shared {}" .format(net_name, net_type, ip_profile, shared)) + created_items = {} isshared = 'false' if shared: isshared = 'true' @@ -524,7 +542,7 @@ class vimconnector(vimconn.vimconnector): network_uuid = self.create_network(network_name=net_name, net_type=net_type, ip_profile=ip_profile, isshared=isshared) if network_uuid is not None: - return network_uuid + return network_uuid, created_items else: raise vimconn.vimconnUnexpectedResponse("Failed create a new network {}".format(net_name)) @@ -771,11 +789,12 @@ class vimconnector(vimconn.vimconnector): return filter_dict - def delete_network(self, net_id): + def delete_network(self, net_id, created_items=None): """ - Method Deletes a tenant network from VIM, provide the network id. - - Returns the network identifier or raise an exception + Removes a tenant network from VIM and its associated elements + :param net_id: VIM identifier of the network, provided by method new_network + :param created_items: dictionary with extra items to be deleted. provided by method new_network + Returns the network identifier or raises an exception upon error or when network is not found """ # ############# Stub code for SRIOV ################# @@ -1523,7 +1542,7 @@ class vimconnector(vimconn.vimconnector): vmname_andid = ''.join(new_vm_name) for net in net_list: - if net['type'] == "SR-IOV" or net['type'] == "PCI-PASSTHROUGH": + if net['type'] == "PCI-PASSTHROUGH": raise vimconn.vimconnNotSupportedException( "Current vCD version does not support type : {}".format(net['type'])) @@ -1554,7 +1573,6 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnNotFoundException("new_vminstance(): Failed create vApp {}: " "(Failed retrieve catalog information {})".format(name, image_id)) - # Set vCPU and Memory based on flavor. vm_cpus = None vm_memory = None @@ -1798,14 +1816,13 @@ class vimconnector(vimconn.vimconnector): #Add PCI passthrough/SRIOV configrations vm_obj = None pci_devices_info = [] - sriov_net_info = [] reserve_memory = False for net in net_list: if net["type"] == "PF" or net["type"] == "PCI-PASSTHROUGH": pci_devices_info.append(net) elif (net["type"] == "VF" or net["type"] == "SR-IOV" or net["type"] == "VFnotShared") and 'net_id'in net: - sriov_net_info.append(net) + reserve_memory = True #Add PCI if len(pci_devices_info) > 0: @@ -1918,7 +1935,8 @@ class vimconnector(vimconn.vimconnector): self.logger.info("new_vminstance(): Attaching net {} to vapp".format(interface_net_name)) self.connect_vapp_to_org_vdc_network(vapp_id, nets[0].get('name')) - type_list = ('PF', 'PCI-PASSTHROUGH', 'VF', 'SR-IOV', 'VFnotShared') + type_list = ('PF', 'PCI-PASSTHROUGH', 'VFnotShared') + nic_type = 'VMXNET3' if 'type' in net and net['type'] not in type_list: # fetching nic type from vnf if 'model' in net: @@ -1938,7 +1956,6 @@ class vimconnector(vimconn.vimconnector): else: self.logger.info("new_vminstance(): adding network adapter "\ "to a network {}".format(nets[0].get('name'))) - nic_type = 'VMXNET3' if net['type'] in ['SR-IOV', 'VF']: nic_type = net['type'] self.add_network_adapter_to_vms(vapp, nets[0].get('name'), @@ -1952,39 +1969,9 @@ class vimconnector(vimconn.vimconnector): if cloud_config: self.cloud_init(vapp,cloud_config) - # ############# Stub code for SRIOV ################# - #Add SRIOV -# if len(sriov_net_info) > 0: -# self.logger.info("Need to add SRIOV adapters {} into VM {}".format(sriov_net_info, -# vmname_andid )) -# sriov_status, vm_obj, vcenter_conect = self.add_sriov(vapp_uuid, -# sriov_net_info, -# vmname_andid) -# if sriov_status: -# self.logger.info("Added SRIOV {} to VM {}".format( -# sriov_net_info, -# vmname_andid) -# ) -# reserve_memory = True -# else: -# self.logger.info("Fail to add SRIOV {} to VM {}".format( -# sriov_net_info, -# vmname_andid) -# ) - # If VM has PCI devices or SRIOV reserve memory for VM if reserve_memory: - memReserve = vm_obj.config.hardware.memoryMB - spec = vim.vm.ConfigSpec() - spec.memoryAllocation = vim.ResourceAllocationInfo(reservation=memReserve) - task = vm_obj.ReconfigVM_Task(spec=spec) - if task: - result = self.wait_for_vcenter_task(task, vcenter_conect) - self.logger.info("Reserved memory {} MB for " - "VM VM status: {}".format(str(memReserve), result)) - else: - self.logger.info("Fail to reserved memory {} to VM {}".format( - str(memReserve), str(vm_obj))) + self.reserve_memory_for_all_vms(vapp, memory_mb) self.logger.debug("new_vminstance(): starting power on vApp {} ".format(vmname_andid)) @@ -2642,13 +2629,12 @@ class vimconnector(vimconn.vimconnector): try: vapp_name = self.get_namebyvappid(vm__vim_uuid) - vapp_resource = vdc_obj.get_vapp(vapp_name) - vapp = VApp(self.client, resource=vapp_resource) if vapp_name is None: 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) - else: - self.logger.info("Deleting vApp {} and UUID {}".format(vapp_name, vm__vim_uuid)) + self.logger.info("Deleting vApp {} and UUID {}".format(vapp_name, vm__vim_uuid)) + vapp_resource = vdc_obj.get_vapp(vapp_name) + vapp = VApp(self.client, resource=vapp_resource) # Delete vApp and wait for status change if task executed and vApp is None. @@ -3032,7 +3018,7 @@ class vimconnector(vimconn.vimconnector): else: self.logger.error("action_vminstance: Failed to {} vApp: {}".format(action, vapp_name)) - def get_vminstance_console(self, vm_id, console_type="vnc"): + def get_vminstance_console(self, vm_id, console_type="novnc"): """ Get a console for the virtual machine Params: @@ -3046,7 +3032,57 @@ class vimconnector(vimconn.vimconnector): port: the http, ssh, ... port suffix: extra text, e.g. the http path and query string """ - raise vimconn.vimconnNotImplemented("Should have implemented this") + console_dict = {} + + if console_type==None or console_type=='novnc': + + url_rest_call = "{}/api/vApp/vm-{}/screen/action/acquireMksTicket".format(self.url, vm_id) + + headers = {'Accept':'application/*+xml;version=' + API_VERSION, + 'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']} + response = self.perform_request(req_type='POST', + url=url_rest_call, + headers=headers) + + if response.status_code == 403: + response = self.retry_rest('GET', url_rest_call) + + if response.status_code != 200: + self.logger.error("REST call {} failed reason : {}"\ + "status code : {}".format(url_rest_call, + response.content, + response.status_code)) + raise vimconn.vimconnException("get_vminstance_console : Failed to get "\ + "VM Mks ticket details") + s = re.search("(.*?)",response.content) + console_dict['server'] = s.group(1) if s else None + s1 = re.search("(\d+)",response.content) + console_dict['port'] = s1.group(1) if s1 else None + + + url_rest_call = "{}/api/vApp/vm-{}/screen/action/acquireTicket".format(self.url, vm_id) + + headers = {'Accept':'application/*+xml;version=' + API_VERSION, + 'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']} + response = self.perform_request(req_type='POST', + url=url_rest_call, + headers=headers) + + if response.status_code == 403: + response = self.retry_rest('GET', url_rest_call) + + if response.status_code != 200: + self.logger.error("REST call {} failed reason : {}"\ + "status code : {}".format(url_rest_call, + response.content, + response.status_code)) + raise vimconn.vimconnException("get_vminstance_console : Failed to get "\ + "VM console details") + s = re.search(">.*?/(vm-\d+.*) - - {10:s} + {9:s} - {11:s} + {10:s} """.format(escape(network_name), is_inherited, gateway_address, subnet_address, dns1, dns2_text, dhcp_enabled, - dhcp_start_address, dhcp_end_address, available_networks, + dhcp_start_address, dhcp_end_address, fence_mode, isshared) headers['Content-Type'] = 'application/vnd.vmware.vcloud.orgVdcNetwork+xml' @@ -5032,6 +5067,10 @@ class vimconnector(vimconn.vimconnector): "network connection section") data = response.content data = data.split('' not in data: self.logger.debug("add_network_adapter PrimaryNIC not in data nic_type {}".format(nic_type)) item = """{} @@ -5041,7 +5080,7 @@ class vimconnector(vimconn.vimconnector): {} {} """.format(primary_nic_index, network_name, nicIndex, - allocation_mode, nic_type) + allocation_mode, vcd_netadapter_type) # Stub for ip_address feature if ip_address: ip_tag = '{}'.format(ip_address) @@ -5060,7 +5099,7 @@ class vimconnector(vimconn.vimconnector): {} {} """.format(network_name, nicIndex, - allocation_mode, nic_type) + allocation_mode, vcd_netadapter_type) # Stub for ip_address feature if ip_address: ip_tag = '{}'.format(ip_address)