def delete_mapping(self, lun_id, host_name): if host_name and len(host_name) > constants.MAX_HOSTNAME_LENGTH: host_name = hash(host_name) host_id = self.find_host(host_name) if host_id: mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id view_id = self.find_mapping_view(mapping_view_name) if view_id: lungroup_id = self.find_lungroup_from_map(view_id) # Remove lun from lungroup. if lun_id and self.check_lun_exist(lun_id): if lungroup_id: lungroup_ids = self.get_lungroupids_by_lunid(lun_id) if lungroup_id in lungroup_ids: self.remove_lun_from_lungroup(lungroup_id, lun_id) else: LOG.info(('Lun is not in lungroup. ' 'Lun id: %(lun_id)s. ' 'lungroup id: %(lungroup_id)s.') % {"lun_id": lun_id, "lungroup_id": lungroup_id}) else: LOG.error("Can't find lun on the array.") raise VolumeBackendAPIException
def detach_volume(self, blockdevice_id): """ Detach ``blockdevice_id`` from whatever host it is attached to. :param unicode blockdevice_id: The unique identifier for the block device being detached. :raises UnknownVolume: If the supplied ``blockdevice_id`` does not exist. :raises UnattachedVolume: If the supplied ``blockdevice_id`` is not attached to anything. :returns: ``None`` """ LOG.info("Call detach_volume blockdevice_id=%s" % blockdevice_id) device = self.get_device_path(blockdevice_id) if device is not None: huawei_utils.remove_scsi_device(device) lun_info = self.restclient.get_lun_info(blockdevice_id) if self.get_attached_to(lun_info) is not None: self.restclient.delete_mapping( blockdevice_id, self._compute_instance_id) else: LOG.error("Volume %s not attached." % blockdevice_id) raise UnattachedVolume(blockdevice_id)
def do_mapping(self, lun_id, hostgroup_id, host_id, tgtportgroup_id=None): """Add hostgroup and lungroup to mapping view.""" lungroup_name = constants.LUNGROUP_PREFIX + host_id mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id lungroup_id = self._find_lungroup(lungroup_name) view_id = self.find_mapping_view(mapping_view_name) map_info = {} LOG.info(( 'do_mapping, lun_group: %(lun_group)s, ' 'view_id: %(view_id)s, lun_id: %(lun_id)s.') % {'lun_group': lungroup_id, 'view_id': view_id, 'lun_id': lun_id}) try: # Create lungroup and add LUN into to lungroup. if lungroup_id is None: lungroup_id = self._create_lungroup(lungroup_name) is_associated = self._is_lun_associated_to_lungroup(lungroup_id, lun_id) if not is_associated: self.associate_lun_to_lungroup(lungroup_id, lun_id) if view_id is None: view_id = self._add_mapping_view(mapping_view_name) self._associate_hostgroup_to_view(view_id, hostgroup_id) self._associate_lungroup_to_view(view_id, lungroup_id) if tgtportgroup_id: self._associate_portgroup_to_view(view_id, tgtportgroup_id) else: if not self.hostgroup_associated(view_id, hostgroup_id): self._associate_hostgroup_to_view(view_id, hostgroup_id) if not self.lungroup_associated(view_id, lungroup_id): self._associate_lungroup_to_view(view_id, lungroup_id) if tgtportgroup_id: if not self._portgroup_associated(view_id, tgtportgroup_id): self._associate_portgroup_to_view(view_id, tgtportgroup_id) version = self.find_array_version() if version >= constants.ARRAY_VERSION: aval_luns = self.find_view_by_id(view_id) map_info["lun_id"] = lun_id map_info["view_id"] = view_id map_info["aval_luns"] = aval_luns except Exception: LOG.error('Error occurred when adding hostgroup and lungroup to ' 'view. Remove lun from lungroup now.') self.remove_lun_from_lungroup(lungroup_id, lun_id) raise VolumeBackendAPIException return map_info
def do_call(self, url=False, data=None, method=None, calltimeout=constants.SOCKET_TIMEOUT): """Send requests to server. Send HTTPS call, get response in JSON. Convert response into Python Object and return it. """ if self.url: url = self.url + url opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie)) urllib2.install_opener(opener) res_json = None LOG.info(('\n\n\n\nRequest URL: %(url)s\n\n' 'Call Method: %(method)s\n\n' 'Request Data: %(data)s\n\n') % {'url': url, 'method': method, 'data': data}) try: urllib2.socket.setdefaulttimeout(calltimeout) req = urllib2.Request(url, data, self.headers) if method: req.get_method = lambda: method res = urllib2.urlopen(req).read().decode("utf-8") if "xx/sessions" not in url: LOG.info(('\n\n\n\nRequest URL: %(url)s\n\n' 'Call Method: %(method)s\n\n' 'Request Data: %(data)s\n\n' 'Response Data:%(res)s\n\n') % {'url': url, 'method': method, 'data': data, 'res': res}) except Exception as err: LOG.error('Bad response from server: %(url)s.Error: %(err)s' % {'url': url, 'err': err}) json_msg = ('{"error":{"code": %s,"description": "Connect to ' 'server error."}}') % constants.ERROR_CONNECT_TO_SERVER res_json = json.loads(json_msg) return res_json try: res_json = json.loads(res) except Exception as err: LOG.error('JSON transfer error: %s.' % err.message) raise return res_json
def _find_alua_info(self, iscsi_conf, initiator_name): """Find ALUA info from xml.""" multipath_type = 0 for ini in iscsi_conf['Initiator']: if ini['Name'] == initiator_name: if 'ALUA' in ini: if ini['ALUA'] != '1' and ini['ALUA'] != '0': msg = ('Invalid ALUA value.' 'ALUA value must be 1 or 0.') LOG.error(msg) raise VolumeBackendAPIException else: multipath_type = ini['ALUA'] break return multipath_type
def add_host_with_check(self, host_name): host_name_before_hash = None if host_name and (len(host_name) > constants.MAX_HOSTNAME_LENGTH): host_name_before_hash = host_name host_name = hash(host_name) host_id = self.find_host(host_name) if host_id: LOG.info(( 'add_host_with_check. ' 'host name: %(name)s, ' 'host id: %(id)s') % {'name': host_name, 'id': host_id}) return host_id try: host_id = self._add_host(host_name, host_name_before_hash) except Exception: LOG.info(( 'Failed to create host: %(name)s. ' 'Check if it exists on the array.') % {'name': host_name}) host_id = self.find_host(host_name) if not host_id: err_msg = (( 'Failed to create host: %(name)s. ' 'Please check if it exists on the array.') % {'name': host_name}) LOG.error(err_msg) raise VolumeBackendAPIException LOG.info(( 'add_host_with_check. ' 'create host success. ' 'host name: %(name)s, ' 'host id: %(id)s') % {'name': host_name, 'id': host_id}) return host_id
def login(self): """Login array.""" login_info = self.configuration urlstr = login_info['RestURL'] url = urlstr + "xx/sessions" data = json.dumps({"username": login_info['UserName'], "password": login_info['UserPassword'], "scope": "0"}) self._init_http_head() result = self.do_call(url, data, calltimeout=constants.LOGIN_SOCKET_TIMEOUT) if (result['error']['code'] != 0) or ("data" not in result): LOG.error("Login error, reason is: %s." % result) return None LOG.info('Login success: %(url)s' % {'url': urlstr}) self.device_id = result['data']['deviceid'] self.url = urlstr + self.device_id self.headers['iBaseToken'] = result['data']['iBaseToken'] return self.device_id
def create_hostgroup_with_check(self, hostgroup_name): """Check if host exists on the array, or create it.""" hostgroup_id = self.find_hostgroup(hostgroup_name) if hostgroup_id: LOG.info(( 'create_hostgroup_with_check. ' 'hostgroup name: %(name)s, ' 'hostgroup id: %(id)s') % {'name': hostgroup_name, 'id': hostgroup_id}) return hostgroup_id try: hostgroup_id = self._create_hostgroup(hostgroup_name) except Exception: LOG.info(( 'Failed to create hostgroup: %(name)s. ' 'Please check if it exists on the array.') % {'name': hostgroup_name}) hostgroup_id = self.find_hostgroup(hostgroup_name) if hostgroup_id is None: err_msg = (( 'Failed to create hostgroup: %(name)s. ' 'Check if it exists on the array.') % {'name': hostgroup_name}) LOG.error(err_msg) raise VolumeBackendAPIException LOG.info(( 'create_hostgroup_with_check. ' 'Create hostgroup success. ' 'hostgroup name: %(name)s, ' 'hostgroup id: %(id)s') % {'name': hostgroup_name, 'id': hostgroup_id}) return hostgroup_id
def initialize_connection_fc(self): """ TODO: Initialize fc connection. """ wwns = huawei_utils.get_fc_wwpns() if not wwns: raise VolumeException # Create hostgroup if not exist. host_id = self.restclient.add_host_with_check( self._compute_instance_id) online_wwns_in_host = ( self.restclient.get_host_online_fc_initiators(host_id)) online_free_wwns = self.restclient.get_online_free_wwns() for wwn in wwns: if (wwn not in online_wwns_in_host and wwn not in online_free_wwns): wwns_in_host = ( self.restclient.get_host_initiators("fc", host_id)) iqns_in_host = ( self.restclient.get_host_initiators("iscsi", host_id)) if not wwns_in_host and not iqns_in_host: self.restclient.remove_host(host_id) LOG.error('Can not add FC initiator to host.') raise VolumeException for wwn in wwns: if wwn in online_free_wwns: self.restclient.add_fc_port_to_host(host_id, wwn) hostgroup_id = self.restclient.add_host_into_hostgroup(host_id) self._host_id = host_id self._hostgroup_id = hostgroup_id
def _assert_data_in_result(self, result, msg): if 'data' not in result: err_msg = ('%s "data" was not in result.' % msg) LOG.error(err_msg) raise VolumeBackendAPIException
def _assert_rest_result(self, result, err_str): if result['error']['code'] != 0: msg = ('%(err)s\nresult: %(res)s.' % {'err': err_str, 'res': result}) LOG.error(msg) raise VolumeBackendAPIException