X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_ro%2Fvimconn_openstack.py;h=4ac5828676b16eaeb8594e6943e32c5ee4566c06;hb=5a3273cfd0fdf8b898091c1d2a2519bc36842c6b;hp=7e6401289a51589faa60fa759f9a5fab7036f0d7;hpb=9317d3077c7aa096379dcb66bf73268b4c2d6406;p=osm%2FRO.git diff --git a/osm_ro/vimconn_openstack.py b/osm_ro/vimconn_openstack.py index 7e640128..4ac58286 100644 --- a/osm_ro/vimconn_openstack.py +++ b/osm_ro/vimconn_openstack.py @@ -84,6 +84,7 @@ class vimconnector(vimconn.vimconnector): if not url: raise TypeError, 'url param can not be NoneType' self.persistent_info = persistent_info + self.availability_zone = persistent_info.get('availability_zone', None) self.session = persistent_info.get('session', {'reload_client': True}) self.nova = self.session.get('nova') self.neutron = self.session.get('neutron') @@ -165,6 +166,9 @@ class vimconnector(vimconn.vimconnector): self.glancev1 = self.session['glancev1'] = glClient.Client('1', session=sess) self.session['reload_client'] = False self.persistent_info['session'] = self.session + # add availablity zone info inside self.persistent_info + self._set_availablity_zones() + self.persistent_info['availability_zone'] = self.availability_zone def __net_os2mano(self, net_list_dict): '''Transform the net openstack format to mano format @@ -700,7 +704,66 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnException('Timeout waiting for instance ' + vm_id + ' to get ' + status, http_code=vimconn.HTTP_Request_Timeout) - def new_vminstance(self,name,description,start,image_id,flavor_id,net_list,cloud_config=None,disk_list=None): + def _get_openstack_availablity_zones(self): + """ + Get from openstack availability zones available + :return: + """ + try: + openstack_availability_zone = self.nova.availability_zones.list() + openstack_availability_zone = [str(zone.zoneName) for zone in openstack_availability_zone + if zone.zoneName != 'internal'] + return openstack_availability_zone + except Exception as e: + return None + + def _set_availablity_zones(self): + """ + Set vim availablity zone + :return: + """ + + if 'availability_zone' in self.config: + vim_availability_zones = self.config.get('availability_zone') + if isinstance(vim_availability_zones, str): + self.availability_zone = [vim_availability_zones] + elif isinstance(vim_availability_zones, list): + self.availability_zone = vim_availability_zones + else: + self.availability_zone = self._get_openstack_availablity_zones() + + def _get_vm_availability_zone(self, availability_zone_index, availability_zone_list): + """ + Return thge availability zone to be used by the created VM. + :return: The VIM availability zone to be used or None + """ + if availability_zone_index is None: + if not self.config.get('availability_zone'): + return None + elif isinstance(self.config.get('availability_zone'), str): + return self.config['availability_zone'] + else: + # TODO consider using a different parameter at config for default AV and AV list match + return self.config['availability_zone'][0] + + vim_availability_zones = self.availability_zone + # check if VIM offer enough availability zones describe in the VNFD + if vim_availability_zones and len(availability_zone_list) <= len(vim_availability_zones): + # check if all the names of NFV AV match VIM AV names + match_by_index = False + for av in availability_zone_list: + if av not in vim_availability_zones: + match_by_index = True + break + if match_by_index: + return vim_availability_zones[availability_zone_index] + else: + return availability_zone_list[availability_zone_index] + else: + raise vimconn.vimconnConflictException("No enough availability zones at VIM for this deployment") + + def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, disk_list=None, + availability_zone_index=None, availability_zone_list=None): '''Adds a VM instance to VIM Params: start: indicates if VM must start or boot in pause mode. Ignored @@ -715,6 +778,26 @@ class vimconnector(vimconn.vimconnector): type: 'virtual', 'PF', 'VF', 'VFnotShared' vim_id: filled/added by this function floating_ip: True/False (or it can be None) + 'cloud_config': (optional) dictionary with: + 'key-pairs': (optional) list of strings with the public key to be inserted to the default user + 'users': (optional) list of users to be inserted, each item is a dict with: + 'name': (mandatory) user name, + 'key-pairs': (optional) list of strings with the public key to be inserted to the user + 'user-data': (optional) string is a text script to be passed directly to cloud-init + 'config-files': (optional). List of files to be transferred. Each item is a dict with: + 'dest': (mandatory) string with the destination absolute path + 'encoding': (optional, by default text). Can be one of: + 'b64', 'base64', 'gz', 'gz+b64', 'gz+base64', 'gzip+b64', 'gzip+base64' + 'content' (mandatory): string with the content of the file + 'permissions': (optional) string with file permissions, typically octal notation '0644' + 'owner': (optional) file owner, string with the format 'owner:group' + 'boot-data-drive': boolean to indicate if user-data must be passed using a boot drive (hard disk) + 'disk_list': (optional) list with additional disks to the VM. Each item is a dict with: + 'image_id': (optional). VIM id of an existing image. If not provided an empty disk must be mounted + 'size': (mandatory) string with the size of the disk in GB + availability_zone_index: Index of availability_zone_list to use for this this VM. None if not AV required + availability_zone_list: list of availability zones given by user in the VNFD descriptor. Ignore if + availability_zone_index is None #TODO ip, security groups Returns the instance identifier ''' @@ -765,7 +848,11 @@ class vimconnector(vimconn.vimconnector): net["ip"] = fixed_ips[0].get("ip_address") else: net["ip"] = None - net_list_vim.append({"port-id": new_port["port"]["id"], "tag": new_port["port"]["name"]}) + + port = {"port-id": new_port["port"]["id"]} + if float(self.nova.api_version.get_string()) >= 2.32: + port["tag"] = new_port["port"]["name"] + net_list_vim.append(port) if net.get('floating_ip', False): net['exit_on_floating_ip_error'] = True @@ -882,15 +969,17 @@ class vimconnector(vimconn.vimconnector): raise vimconn.vimconnException('Timeout creating volumes for instance ' + name, http_code=vimconn.HTTP_Request_Timeout) - - self.logger.debug("nova.servers.create({}, {}, {}, nics={}, meta={}, security_groups={}," \ - "availability_zone={}, key_name={}, userdata={}, config_drive={}, " \ - "block_device_mapping={})".format(name, image_id, flavor_id, net_list_vim, - metadata, security_groups, self.config.get('availability_zone'), - self.config.get('keypair'), userdata, config_drive, block_device_mapping)) + # get availability Zone + vm_av_zone = self._get_vm_availability_zone(availability_zone_index, availability_zone_list) + + self.logger.debug("nova.servers.create({}, {}, {}, nics={}, meta={}, security_groups={}, " + "availability_zone={}, key_name={}, userdata={}, config_drive={}, " + "block_device_mapping={})".format(name, image_id, flavor_id, net_list_vim, metadata, + security_groups, vm_av_zone, self.config.get('keypair'), + userdata, config_drive, block_device_mapping)) server = self.nova.servers.create(name, image_id, flavor_id, nics=net_list_vim, meta=metadata, security_groups=security_groups, - availability_zone=self.config.get('availability_zone'), + availability_zone=vm_av_zone, key_name=self.config.get('keypair'), userdata=userdata, config_drive=config_drive,