X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FRO.git;a=blobdiff_plain;f=RO-VIM-vmware%2Fosm_rovim_vmware%2Fvimconn_vmware.py;h=171f7d4451e38102c8c21ea935c8988bcc182f03;hp=e37c419675fceb91ed705e74c101a8c8b2abb3a4;hb=57dadcfd0fcf3c8e933602e2fb57f32658d9c845;hpb=7d782eff123e5b44d41437377ccca66ad1e8b21b diff --git a/RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py b/RO-VIM-vmware/osm_rovim_vmware/vimconn_vmware.py index e37c4196..171f7d44 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. # @@ -57,7 +57,7 @@ import time import uuid # import httplib #For python3 -#import http.client +#import http.client # TODO py3 check import hashlib import socket import struct @@ -446,9 +446,7 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnNotFoundException("Fail to get tenant {}".format(tenant_id)) lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} - #For python3 - #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} + namespaces = {prefix: uri for prefix, uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" vdc_remove_href = lxmlroot_respond.find("xmlns:Link[@rel='remove']",namespaces).attrib['href'] vdc_remove_href = vdc_remove_href + '?recursive=true&force=true' @@ -503,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 @@ -520,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. @@ -528,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' @@ -541,9 +542,19 @@ 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 + + import traceback + traceback.print_stack() + + 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: @@ -976,9 +987,7 @@ class vimconnector(vimconn.vimconnector): 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} - #For python3 - #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} + namespaces = {prefix: uri for prefix, uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" catalogItems_section = lxmlroot_respond.find("xmlns:CatalogItems",namespaces) @@ -999,9 +1008,7 @@ class vimconnector(vimconn.vimconnector): image_id)) lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} - #For python3 - #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} + 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'] @@ -1409,11 +1416,8 @@ class vimconnector(vimconn.vimconnector): return None # UUID has following format https://host/api/vApp/vapp-30da58a3-e7c7-4d09-8f68-d4c8201169cf try: - refs = filter(lambda ref: ref.name == vapp_name and ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml', - vdc.ResourceEntities.ResourceEntity) - #For python3 - #refs = [ref for ref in vdc.ResourceEntities.ResourceEntity\ - # if ref.name == vapp_name and ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml'] + refs = [ref for ref in vdc.ResourceEntities.ResourceEntity \ + if ref.name == vapp_name and ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml'] if len(refs) == 1: return refs[0].href.split("vapp")[1][1:] except Exception as e: @@ -1435,12 +1439,8 @@ class vimconnector(vimconn.vimconnector): :param vapp_uuid: """ try: - refs = filter(lambda ref: - ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml', - vdc.ResourceEntities.ResourceEntity) - #For python3 - #refs = [ref for ref in vdc.ResourceEntities.ResourceEntity\ - # if ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml'] + refs = [ref for ref in vdc.ResourceEntities.ResourceEntity\ + if ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml'] for ref in refs: vappid = ref.href.split("vapp")[1][1:] # find vapp with respected vapp uuid @@ -1926,9 +1926,7 @@ class vimconnector(vimconn.vimconnector): if primary_netname is not None: self.logger.debug("new_vminstance(): Filtering by net name {}".format(interface_net_name)) - nets = filter(lambda n: n.get('name') == interface_net_name, self.get_network_list()) - #For python3 - #nets = [n for n in self.get_network_list() if n.get('name') == interface_net_name] + nets = [n for n in self.get_network_list() if n.get('name') == interface_net_name] if len(nets) == 1: self.logger.info("new_vminstance(): Found requested network: {}".format(nets[0].get('name'))) @@ -3062,7 +3060,6 @@ class vimconnector(vimconn.vimconnector): except XmlElementTree.ParseError as Err: self.logger.debug("ParseError in response from NSX Manager {}".format(Err.message), exc_info=True) - def action_vminstance(self, vm__vim_uuid=None, action_dict=None, created_items={}): """Send and action over a VM instance from VIM Returns the vm_id if the action was successfully sent to the VIM""" @@ -3073,7 +3070,7 @@ class vimconnector(vimconn.vimconnector): org, vdc = self.get_vdc_details() if vdc is None: - raise vimconn.vimconnException("Failed to get a reference of VDC for a tenant {}".format(self.tenant_name)) + raise vimconn.vimconnException("Failed to get a reference of VDC for a tenant {}".format(self.tenant_name)) vapp_name = self.get_namebyvappid(vm__vim_uuid) if vapp_name is None: @@ -3107,9 +3104,7 @@ class vimconnector(vimconn.vimconnector): result = self.client.get_task_monitor().wait_for_success(task=poweron_task) self.instance_actions_result("resume", result, vapp_name) elif "shutoff" in action_dict or "shutdown" in action_dict: - action_name , value = action_dict.items()[0] - #For python3 - #action_name , value = list(action_dict.items())[0] + action_name , value = list(action_dict.items())[0] self.logger.info("action_vminstance: {} vApp: {}".format(action_name, vapp_name)) shutdown_task = vapp.shutdown() result = self.client.get_task_monitor().wait_for_success(task=shutdown_task) @@ -3285,7 +3280,6 @@ class vimconnector(vimconn.vimconnector): The return network uuid. network_uuid: network_id """ - if not network_name: self.logger.debug("get_network_id_by_name() : Network name is empty") return None @@ -3294,9 +3288,7 @@ class vimconnector(vimconn.vimconnector): org_dict = self.get_org(self.org_uuid) if org_dict and 'networks' in org_dict: org_network_dict = org_dict['networks'] - for net_uuid,net_name in org_network_dict.items(): - #For python3 - #for net_uuid,net_name in org_network_dict.items(): + for net_uuid, net_name in org_network_dict.items(): if net_name == network_name: return net_uuid @@ -3305,6 +3297,81 @@ class vimconnector(vimconn.vimconnector): return None + def get_physical_network_by_name(self, physical_network_name): + ''' + Methos returns uuid of physical network which passed + Args: + physical_network_name: physical network name + Returns: + UUID of physical_network_name + ''' + try: + client_as_admin = self.connect_as_admin() + if not client_as_admin: + raise vimconn.vimconnConnectionException("Failed to connect vCD.") + url_list = [self.url, '/api/admin/vdc/', self.tenant_id] + vm_list_rest_call = ''.join(url_list) + + if client_as_admin._session: + headers = {'Accept':'application/*+xml;version=' + API_VERSION, + 'x-vcloud-authorization': client_as_admin._session.headers['x-vcloud-authorization']} + + response = self.perform_request(req_type='GET', + url=vm_list_rest_call, + headers=headers) + + provider_network = None + available_network = None + add_vdc_rest_url = None + + if response.status_code != requests.codes.ok: + self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call, + response.status_code)) + return None + else: + try: + vm_list_xmlroot = XmlElementTree.fromstring(response.content) + for child in vm_list_xmlroot: + + if child.tag.split("}")[1] == 'ProviderVdcReference': + provider_network = child.attrib.get('href') + # application/vnd.vmware.admin.providervdc+xml + if child.tag.split("}")[1] == 'Link': + if child.attrib.get('type') == 'application/vnd.vmware.vcloud.orgVdcNetwork+xml' \ + and child.attrib.get('rel') == 'add': + 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)) + return None + + # find pvdc provided available network + response = self.perform_request(req_type='GET', + url=provider_network, + headers=headers) + + if response.status_code != requests.codes.ok: + self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call, + response.status_code)) + return None + + try: + vm_list_xmlroot = XmlElementTree.fromstring(response.content) + for child in vm_list_xmlroot.iter(): + if child.tag.split("}")[1] == 'AvailableNetworks': + for networks in child.iter(): + if networks.attrib.get('href') is not None and networks.attrib.get('name') is not None: + if networks.attrib.get('name') == physical_network_name: + network_url = networks.attrib.get('href') + available_network = network_url[network_url.rindex('/')+1:] + break + except Exception as e: + return None + + return available_network + except Exception as e: + self.logger.error("Error while getting physical network: {}".format(e)) + def list_org_action(self): """ Method leverages vCloud director and query for available organization for particular user @@ -3451,11 +3518,8 @@ class vimconnector(vimconn.vimconnector): vm_list_rest_call = ''.join(url_list) if not (not vca.vcloud_session or not vca.vcloud_session.organization): - refs = filter(lambda ref: ref.name == vdc_name and ref.type_ == 'application/vnd.vmware.vcloud.vdc+xml', - vca.vcloud_session.organization.Link) - #For python3 - #refs = [ref for ref in vca.vcloud_session.organization.Link if ref.name == vdc_name and\ - # ref.type_ == 'application/vnd.vmware.vcloud.vdc+xml'] + refs = [ref for ref in vca.vcloud_session.organization.Link if ref.name == vdc_name and + ref.type_ == 'application/vnd.vmware.vcloud.vdc+xml'] if len(refs) == 1: response = Http.get(url=vm_list_rest_call, headers=vca.vcloud_session.get_vcloud_headers(), @@ -3789,6 +3853,7 @@ class vimconnector(vimconn.vimconnector): try: vm_list_xmlroot = XmlElementTree.fromstring(response.content) for child in vm_list_xmlroot: + if child.tag.split("}")[1] == 'ProviderVdcReference': provider_network = child.attrib.get('href') # application/vnd.vmware.admin.providervdc+xml @@ -3805,6 +3870,7 @@ class vimconnector(vimconn.vimconnector): response = self.perform_request(req_type='GET', url=provider_network, headers=headers) + if response.status_code != requests.codes.ok: self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call, response.status_code)) @@ -3890,31 +3956,61 @@ class vimconnector(vimconn.vimconnector): dns2_text = "" if len(dns_list) >= 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: @@ -4399,9 +4495,7 @@ class vimconnector(vimconn.vimconnector): return None try: lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} - #For python3 - #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} + namespaces = {prefix: uri for prefix, uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" for item in lxmlroot_respond.iterfind('xmlns:Item',namespaces): @@ -5538,9 +5632,7 @@ class vimconnector(vimconn.vimconnector): try: #Find but type & max of instance IDs assigned to disks lxmlroot_respond = lxmlElementTree.fromstring(response.content) - namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} - #For python3 - #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix} + namespaces = {prefix: uri for prefix, uri in lxmlroot_respond.nsmap.items() if prefix} namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5" instance_id = 0 for item in lxmlroot_respond.iterfind('xmlns:Item',namespaces): @@ -6278,14 +6370,12 @@ class vimconnector(vimconn.vimconnector): used_ids = list(self.persistent_info["used_vlanIDs"].values()) for vlanID_range in self.config.get('vlanID_range'): - start_vlanid , end_vlanid = vlanID_range.split("-") + start_vlanid, end_vlanid = vlanID_range.split("-") if start_vlanid > end_vlanid: raise vimconn.vimconnConflictException("Invalid vlan ID range {}".format( vlanID_range)) - for id in xrange(int(start_vlanid), int(end_vlanid) + 1): - #For python3 - #for id in range(int(start_vlanid), int(end_vlanid) + 1): + for id in range(int(start_vlanid), int(end_vlanid) + 1): if id not in used_ids: vlan_id = id self.persistent_info["used_vlanIDs"][network_name] = vlan_id