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