def format_vimconn_exception(self, e): """Params: an Exception object Returns: Raises the exception 'e' passed in mehtod parameters """ self.conn = None self.conn_vpc = None raise vimconn.VimConnConnectionException( type(e).__name__ + ": " + str(e))
def get_vminstance(self, vm_id): """Returns the VM instance information from VIM""" self.logger.debug('VIM get_vminstance with args: {}'.format(locals())) try: instance = self.fos_api.fdu.instance_info(vm_id) except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e)) if instance is None: raise vimconn.VimConnNotFoundException('VM with id {} not found!'.format(vm_id)) return instance.to_json()
def delete_flavor(self, flavor_id): """Deletes a tenant flavor from VIM identify by its id Returns the used id or raise an exception""" try: self.fos_api.flavor.remove(flavor_id) except fimapi.FIMNotFoundException as fnfe: raise vimconn.VimConnNotFoundException( "Flavor {} not found at VIM (already deleted?). Error {}".format(flavor_id, fnfe)) except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e)) return flavor_id
def check_vim_connectivity(self): """Checks VIM can be reached and user credentials are ok. Returns None if success or raised VimConnConnectionException, VimConnAuthException, ... """ try: self.fos_api.node.list() return None except fimapi.FIMAuthExcetpion as fae: raise vimconn.VimConnAuthException("Unable to authenticate to the VIM. Error {}".format(fae)) except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e))
def get_flavor(self, flavor_id): """Obtain flavor details from the VIM Returns the flavor dict details {'id':<>, 'name':<>, other vim specific } Raises an exception upon error or if not found """ self.logger.debug('VIM get_flavor with args: {}'.format(locals())) try: r = self.fos_api.flavor.get(flavor_id) except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e)) if r is None: raise vimconn.VimConnNotFoundException("Flavor not found at VIM") return {'id': r.get('uuid'), 'name': r.get('name'), 'fos': r}
def get_image_id_from_path(self, path): """Get the image id from image path in the VIM database. Returns the image_id or raises a vimconnNotFoundException """ self.logger.debug('VIM get_image_id_from_path with args: {}'.format(locals())) try: imgs = self.fos_api.image.list() except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e)) res = [x.get('uuid') for x in imgs if x.get('uri') == path] if len(res) == 0: raise vimconn.VimConnNotFoundException("Image with this path was not found") return res[0]
def get_network_list(self, filter_dict={}): """Obtain tenant networks of VIM :param filter_dict: (optional) contains entries to return only networks that matches ALL entries: name: string => returns only networks with this name id: string => returns networks with this VIM id, this imply returns one network at most shared: boolean >= returns only networks that are (or are not) shared tenant_id: sting => returns only networks that belong to this tenant/project (not used yet) admin_state_up: boolean => returns only networks that are (or are not) in admin state active (not used yet) status: 'ACTIVE','ERROR',... => filter networks that are on this status Returns the network list of dictionaries. each dictionary contains: 'id': (mandatory) VIM network id 'name': (mandatory) VIM network name 'status': (mandatory) can be 'ACTIVE', 'INACTIVE', 'DOWN', 'BUILD', 'ERROR', 'VIM_ERROR', 'OTHER' 'network_type': (optional) can be 'vxlan', 'vlan' or 'flat' 'segmentation_id': (optional) in case network_type is vlan or vxlan this field contains the segmentation id 'error_msg': (optional) text that explains the ERROR status other VIM specific fields: (optional) whenever possible using the same naming of filter_dict param List can be empty if no network map the filter_dict. Raise an exception only upon VIM connectivity, authorization, or some other unspecific error """ self.logger.debug('get_network_list: {}'.format(filter_dict)) res = [] try: nets = self.fos_api.network.list() except Exception as e: raise vimconn.VimConnConnectionException( "Cannot get network list from VIM, connection error. Error {}".format(e)) filters = [ partial(self.__name_filter, filter_name=filter_dict.get('name')), partial(self.__id_filter, filter_id=filter_dict.get('id')) ] r1 = [] for n in nets: match = True for f in filters: match = match and f(n) if match: r1.append(n) for n in r1: osm_net = { 'id': n.get('uuid'), 'name': n.get('name'), 'status': 'ACTIVE' } res.append(osm_net) return res
def get_image_list(self, filter_dict={}): """Obtain tenant images from VIM Filter_dict can be: name: image name id: image uuid checksum: image checksum location: image path Returns the image list of dictionaries: [{<the fields at Filter_dict plus some VIM specific>}, ...] List can be empty """ self.logger.debug('VIM get_image_list args: {}'.format(locals())) r = [] try: fimgs = self.fos_api.image.list() except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e)) filters = [ partial(self.__name_filter, filter_name=filter_dict.get('name')), partial(self.__id_filter, filter_id=filter_dict.get('id')), partial(self.__checksum_filter, filter_checksum=filter_dict.get('checksum')) ] r1 = [] for i in fimgs: match = True for f in filters: match = match and f(i) if match: r1.append(i) for i in r1: img_info = { 'name': i.get('name'), 'id': i.get('uuid'), 'checksum': i.get('checksum'), 'location': i.get('uri'), 'fos': i } r.append(img_info) return r
def get_flavor_id_from_data(self, flavor_dict): """Obtain flavor id that match the flavor description Params: 'flavor_dict': dictionary that contains: 'disk': main hard disk in GB 'ram': meomry in MB 'vcpus': number of virtual cpus #TODO: complete parameters for EPA Returns the flavor_id or raises a vimconnNotFoundException """ self.logger.debug('VIM get_flavor_id_from_data with args : {}'.format(locals())) try: flvs = self.fos_api.flavor.list() except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e)) r = [x.get('uuid') for x in flvs if (x.get('cpu_min_count') == flavor_dict.get('vcpus') and x.get('ram_size_mb') == flavor_dict.get('ram') and x.get('storage_size_gb') == flavor_dict.get('disk'))] if len(r) == 0: raise vimconn.VimConnNotFoundException("No flavor found") return r[0]
def new_flavor(self, flavor_data): """Adds a tenant flavor to VIM flavor_data contains a dictionary with information, keys: name: flavor name ram: memory (cloud type) in MBytes vpcus: cpus (cloud type) extended: EPA parameters - numas: #items requested in same NUMA memory: number of 1G huge pages memory paired-threads|cores|threads: number of paired hyperthreads, complete cores OR individual threads interfaces: # passthrough(PT) or SRIOV interfaces attached to this numa - name: interface name dedicated: yes|no|yes:sriov; for PT, SRIOV or only one SRIOV for the physical NIC bandwidth: X Gbps; requested guarantee bandwidth vpci: requested virtual PCI address disk: disk size is_public: #TODO to concrete Returns the flavor identifier""" self.logger.debug('VIM new_flavor with args: {}'.format(locals())) flv_id = '{}'.format(uuid.uuid4()) desc = { 'uuid': flv_id, 'name': flavor_data.get('name'), 'cpu_arch': self.arch, 'cpu_min_count': flavor_data.get('vcpus'), 'cpu_min_freq': 0, 'ram_size_mb': float(flavor_data.get('ram')), 'storage_size_gb': float(flavor_data.get('disk')) } try: self.fos_api.flavor.add(desc) except fimapi.FIMAResouceExistingException as free: raise vimconn.VimConnConflictException("Flavor {} already exist at VIM. Error {}".format(flv_id, free)) except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e)) return flv_id
def new_image(self, image_dict): """ Adds a tenant image to VIM. imge_dict is a dictionary with: name: name disk_format: qcow2, vhd, vmdk, raw (by default), ... location: path or URI public: "yes" or "no" metadata: metadata of the image Returns the image id or raises an exception if failed """ self.logger.debug('VIM new_image with args: {}'.format(locals())) img_id = '{}'.format(uuid.uuid4()) desc = { 'name': image_dict.get('name'), 'uuid': img_id, 'uri': image_dict.get('location'), 'format': image_dict.get('disk_format') } try: self.fos_api.image.add(desc) except fimapi.FIMAResouceExistingException as free: raise vimconn.VimConnConflictException("Image {} already exist at VIM. Error {}".format(img_id, free)) except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e)) return img_id
def action_vminstance(self, vm_id, action_dict, created_items={}): """ Send and action over a VM instance. Returns created_items if the action was successfully sent to the VIM. created_items is a dictionary with items that :param vm_id: VIM identifier of the VM, provided by method new_vminstance :param action_dict: dictionary with the action to perform :param created_items: provided by method new_vminstance is a dictionary with key-values that will be passed to the method delete_vminstance. Can be used to store created ports, volumes, etc. Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same as not present. This method can modify this value :return: None, or a console dict """ self.logger.debug('VIM action_vminstance with args: {}'.format(locals())) nid = self.fdu_node_map.get(vm_id) if nid is None: raise vimconn.VimConnNotFoundException('No node for this VM') try: instance = self.fos_api.fdu.instance_info(vm_id) if "start" in action_dict: if instance.get('status') == 'CONFIGURE': self.fos_api.fdu.start(vm_id) elif instance.get('status') == 'PAUSE': self.fos_api.fdu.resume(vm_id) else: raise vimconn.VimConnConflictException('Cannot start from current state: {}'.format( instance.get('status'))) elif "pause" in action_dict: if instance.get('status') == 'RUN': self.fos_api.fdu.pause(vm_id) else: raise vimconn.VimConnConflictException('Cannot pause from current state: {}'.format( instance.get('status'))) elif "resume" in action_dict: if instance.get('status') == 'PAUSE': self.fos_api.fdu.resume(vm_id) else: raise vimconn.VimConnConflictException('Cannot resume from current state: {}'.format( instance.get('status'))) elif "shutoff" in action_dict or "shutdown" or "forceOff" in action_dict: if instance.get('status') == 'RUN': self.fos_api.fdu.stop(vm_id) else: raise vimconn.VimConnConflictException('Cannot shutoff from current state: {}'.format( instance.get('status'))) elif "terminate" in action_dict: if instance.get('status') == 'RUN': self.fos_api.fdu.stop(vm_id) self.fos_api.fdu.clean(vm_id) self.fos_api.fdu.undefine(vm_id) # self.fos_api.fdu.offload(vm_id) elif instance.get('status') == 'CONFIGURE': self.fos_api.fdu.clean(vm_id) self.fos_api.fdu.undefine(vm_id) # self.fos_api.fdu.offload(vm_id) elif instance.get('status') == 'PAUSE': self.fos_api.fdu.resume(vm_id) self.fos_api.fdu.stop(vm_id) self.fos_api.fdu.clean(vm_id) self.fos_api.fdu.undefine(vm_id) # self.fos_api.fdu.offload(vm_id) else: raise vimconn.VimConnConflictException('Cannot terminate from current state: {}'.format( instance.get('status'))) elif "rebuild" in action_dict: raise vimconn.VimConnNotImplemented("Rebuild not implemented") elif "reboot" in action_dict: if instance.get('status') == 'RUN': self.fos_api.fdu.stop(vm_id) self.fos_api.fdu.start(vm_id) else: raise vimconn.VimConnConflictException('Cannot reboot from current state: {}'.format( instance.get('status'))) except Exception as e: raise vimconn.VimConnConnectionException("VIM not reachable. Error {}".format(e))