Eliminate randomness in encode_name&encode_host_name methods

Use 'md5' instead of 'hash' to generate a
shorter lun name and host name for Huawei backend.

Change-Id: Icfac5f34d3caaf6019e39802e5da44428593d927
Closes-Bug: #1658725
(cherry picked from commit 36471cfc0d)
This commit is contained in:
zengyingzhe 2017-08-04 18:19:52 +08:00
parent dd0e46963c
commit 740c7153d6
6 changed files with 279 additions and 174 deletions

View File

@ -60,8 +60,17 @@ PROVIDER_LOCATION_WITH_HYPERMETRO = (
SNAP_PROVIDER_LOCATION = '{"huawei_snapshot_id": "11"}'
HOST = 'ubuntu001@backend001#OpenStack_Pool'
ENCODE_HOST_NAME = huawei_utils.encode_host_name(HOST)
HOST2 = 'ubuntu002@backend002#OpenStack_Pool'
OLD_ENCODE_HOST_NAME = huawei_utils.old_encode_host_name(HOST2)
ID = '21ec7341-9256-497b-97d9-ef48edcf0635'
ENCODE_NAME = huawei_utils.encode_name(ID)
ID2 = 'ee00eb7c-40dc-4256-bfea-6c3a16ab850d'
OLD_ENCODE_NAME = huawei_utils.old_encode_name(ID2)
METADATA = {}
TEST_PAIR_ID = "3400a30d844d0004"
VOL_METADATA = [{'key': 'hypermetro_id', 'value': '11'},
@ -273,6 +282,16 @@ FAKE_GET_HOST_RESPONSE = """
}
"""
FAKE_PATCH_GET_HOST_RESPONSE = """
{
"error": {
"code": 0
},
"data":[{"NAME": "ubuntuc001",
"ID": "1"}]
}
"""
# A fake response of success response storage
FAKE_COMMON_SUCCESS_RESPONSE = """
{
@ -1257,6 +1276,9 @@ MAP_COMMAND_TO_FAKE_RESPONSE['/lun/11/PUT'] = (
MAP_COMMAND_TO_FAKE_RESPONSE['/lun?filter=NAME::%s/GET' % ENCODE_NAME] = (
json.dumps(FAKE_QUERY_ALL_LUN_RESPONSE))
MAP_COMMAND_TO_FAKE_RESPONSE['/lun?filter=NAME::%s/GET' % OLD_ENCODE_NAME] = (
json.dumps(FAKE_QUERY_ALL_LUN_RESPONSE))
MAP_COMMAND_TO_FAKE_RESPONSE['/lun/associate?TYPE=11&ASSOCIATEOBJTYPE=256'
'&ASSOCIATEOBJID=11/GET'] = (
FAKE_LUN_ASSOCIATE_RESPONSE)
@ -1361,6 +1383,10 @@ MAP_COMMAND_TO_FAKE_RESPONSE['/snapshot/11/DELETE'] = (
MAP_COMMAND_TO_FAKE_RESPONSE['/snapshot?filter=NAME::%s/GET' % ENCODE_NAME] = (
json.dumps(FAKE_SNAPSHOT_LIST_INFO_RESPONSE))
MAP_COMMAND_TO_FAKE_RESPONSE['/snapshot?filter=NAME::%s/GET'
% OLD_ENCODE_NAME] = (
json.dumps(FAKE_SNAPSHOT_LIST_INFO_RESPONSE))
# mock QoS info map
MAP_COMMAND_TO_FAKE_RESPONSE['/ioclass/11/GET'] = (
FAKE_LUN_GET_SUCCESS_RESPONSE)
@ -1416,9 +1442,12 @@ MAP_COMMAND_TO_FAKE_RESPONSE['/iscsi_initiator/remove_iscsi_from_host/PUT'] = (
MAP_COMMAND_TO_FAKE_RESPONSE['/iscsi_initiator/'
'iqn.1993-08.debian:01:ec2bff7ac3a3/PUT'] = (
FAKE_ISCSI_INITIATOR_RESPONSE)
# mock host info map
MAP_COMMAND_TO_FAKE_RESPONSE['/host?range=[0-65535]/GET'] = (
FAKE_GET_ALL_HOST_INFO_RESPONSE)
MAP_COMMAND_TO_FAKE_RESPONSE['/host?filter=NAME::%s/GET' % ENCODE_HOST_NAME
] = FAKE_PATCH_GET_HOST_RESPONSE
MAP_COMMAND_TO_FAKE_RESPONSE['/host?filter=NAME::%s/GET' % OLD_ENCODE_HOST_NAME
] = FAKE_PATCH_GET_HOST_RESPONSE
MAP_COMMAND_TO_FAKE_RESPONSE['/host/1/DELETE'] = (
FAKE_COMMON_SUCCESS_RESPONSE)
@ -2124,12 +2153,12 @@ class FakeClient(rest_client.RestClient):
log_filter_flag=False):
url = url.replace('http://192.0.2.69:8082/deviceManager/rest', '')
command = url.replace('/210235G7J20000000000/', '')
data = json.dumps(data) if data else None
data = FAKE_COMMON_SUCCESS_RESPONSE
if method:
command = command + "/" + method
for item in MAP_COMMAND_TO_FAKE_RESPONSE.keys():
for item in MAP_COMMAND_TO_FAKE_RESPONSE:
if command == item:
data = MAP_COMMAND_TO_FAKE_RESPONSE[item]
if self.test_fail:
@ -2251,11 +2280,17 @@ class HuaweiTestBase(test.TestCase):
def test_encode_name(self):
lun_name = huawei_utils.encode_name(self.volume.id)
self.assertEqual('21ec7341-ca82ece92e1ac480c963f1', lun_name)
# The hash value is different between py27 and py34.
# So we use assertIn.
self.assertIn(lun_name, ('21ec7341-4687000622165227970',
'21ec7341-7953146827712520106'))
@ddt.data({'name': '9548e5e7-ca1c-46bf-b132',
'expected': '9548e5e7-ca1c-46bf-b132'},
{'name': '9548e5e7ca1c46bfb132891b425a81f',
'expected': '9548e5e7ca1c46bfb132891b425a81f'},
{'name': '9548e5e7-ca1c-46bf-b132-891b425a81f5',
'expected': '45d6964d772b2efcaad0e3c59538ecc'})
@ddt.unpack
def test_encode_host_name(self, name, expected):
self.assertEqual(expected, huawei_utils.encode_host_name(name))
@mock.patch.object(rest_client, 'RestClient')
def test_create_snapshot_success(self, mock_client):
@ -2338,6 +2373,77 @@ class HuaweiTestBase(test.TestCase):
metadata = huawei_utils.get_snapshot_metadata(snapshot)
self.assertEqual(expect, metadata)
@ddt.data(
{
'volume': fake_volume.fake_volume_obj(
admin_contex, provider_location=PROVIDER_LOCATION),
'expect': ('11', '6643e8c1004c5f6723e9f454003'),
},
{
'volume': fake_volume.fake_volume_obj(
admin_contex, id=ID),
'expect': ('1', None),
},
{
'volume': fake_volume.fake_volume_obj(
admin_contex, id=ID2),
'expect': ('1', None),
},
{
'volume': fake_volume.fake_volume_obj(
admin_contex, id='fake_id'),
'expect': (None, None),
}
)
@ddt.unpack
def test_get_volume_lun_id(self, volume, expect):
volume_id = huawei_utils.get_volume_lun_id(self.driver.client,
volume)
self.assertEqual(expect, volume_id)
@ddt.data(
{
'snapshot': fake_snapshot.fake_snapshot_obj(
admin_contex,
provider_location=SNAP_PROVIDER_LOCATION),
'expect': '11',
},
{
'snapshot': fake_snapshot.fake_snapshot_obj(
admin_contex, id=ID),
'expect': '11',
},
{
'snapshot': fake_snapshot.fake_snapshot_obj(
admin_contex, id=ID2),
'expect': '11',
},
{
'snapshot': fake_snapshot.fake_snapshot_obj(
admin_contex, id='fake_id'),
'expect': None
}
)
@ddt.unpack
def test_get_snapshot_id(self, snapshot, expect):
snapshot_id = huawei_utils.get_snapshot_id(self.driver.client,
snapshot)
self.assertEqual(expect, snapshot_id)
@ddt.data(
{'host_name': HOST,
'expect': '1'},
{'host_name': HOST2,
'expect': '1'},
{'host_name': 'fake_host_name',
'expect': None},
)
@ddt.unpack
def test_get_host_id(self, host_name, expect):
host_id = huawei_utils.get_host_id(self.driver.client,
host_name)
self.assertEqual(expect, host_id)
@ddt.ddt
class HuaweiISCSIDriverTestCase(HuaweiTestBase):

View File

@ -61,7 +61,7 @@ NO_MIGRATION_LICENSE = 1073806606
THICK_LUNTYPE = 0
THIN_LUNTYPE = 1
MAX_HOSTNAME_LENGTH = 31
MAX_NAME_LENGTH = 31
MAX_VOL_DESCRIPTION = 170
PORT_NUM_PER_CONTR = 2
PWD_EXPIRED = 3

View File

@ -431,8 +431,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
return model_update
def _delete_volume(self, volume):
metadata = huawei_utils.get_lun_metadata(volume)
lun_id = metadata.get('huawei_lun_id')
lun_id, lun_wwn = huawei_utils.get_volume_lun_id(self.client, volume)
if not lun_id:
return
@ -578,20 +577,19 @@ class HuaweiBaseDriver(driver.VolumeDriver):
def update_migrated_volume(self, ctxt, volume, new_volume,
original_volume_status=None):
original_name = huawei_utils.encode_name(volume.id)
current_name = huawei_utils.encode_name(new_volume.id)
orig_lun_name = huawei_utils.encode_name(volume.id)
new_lun_id, lun_wwn = huawei_utils.get_volume_lun_id(
self.client, new_volume)
lun_id = self.client.get_lun_id_by_name(current_name)
try:
self.client.rename_lun(lun_id, original_name)
self.client.rename_lun(new_lun_id, orig_lun_name)
except exception.VolumeBackendAPIException:
LOG.error(_LE('Unable to rename lun %s on array.'), current_name)
LOG.error(_LE('Unable to rename lun %s on array.'), new_lun_id)
return {'_name_id': new_volume.name_id}
LOG.debug("Renamed lun from %(current_name)s to %(original_name)s "
"successfully.",
{'current_name': current_name,
'original_name': original_name})
LOG.debug("Renamed lun %(id)s to %(name)s successfully.",
{'id': new_lun_id,
'name': orig_lun_name})
model_update = {'_name_id': None}
@ -647,12 +645,9 @@ class HuaweiBaseDriver(driver.VolumeDriver):
pool_name = host['capabilities']['pool_name']
pools = self.client.get_all_pools()
pool_info = self.client.get_pool_info(pool_name, pools)
src_volume_name = huawei_utils.encode_name(volume.id)
dst_volume_name = six.text_type(hash(src_volume_name))
metadata = huawei_utils.get_lun_metadata(volume)
src_id = metadata['huawei_lun_id']
dst_volume_name = six.text_type(uuid.uuid4())
src_id, lun_wwn = huawei_utils.get_volume_lun_id(self.client, volume)
opts = None
qos = None
if new_type:
@ -729,23 +724,17 @@ class HuaweiBaseDriver(driver.VolumeDriver):
opts = self._get_volume_params(volume_type)
if (opts.get('hypermetro') == 'true'
and opts.get('replication_enabled') == 'true'):
err_msg = _("Hypermetro and Replication can not be "
"used in the same volume_type.")
LOG.error(err_msg)
raise exception.VolumeBackendAPIException(data=err_msg)
msg = _("Hypermetro and Replication can not be "
"used in the same volume_type.")
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
snapshotname = huawei_utils.encode_name(snapshot.id)
metadata = huawei_utils.get_snapshot_metadata(snapshot)
snapshot_id = metadata.get('huawei_snapshot_id')
snapshot_id = huawei_utils.get_snapshot_id(self.client, snapshot)
if snapshot_id is None:
snapshot_id = self.client.get_snapshot_id_by_name(snapshotname)
if snapshot_id is None:
err_msg = (_(
'create_volume_from_snapshot: Snapshot %(name)s '
'does not exist.')
% {'name': snapshotname})
LOG.error(err_msg)
raise exception.VolumeBackendAPIException(data=err_msg)
msg = _('create_volume_from_snapshot: Snapshot %(name)s '
'does not exist.') % {'name': snapshot.id}
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
lun_params, lun_info, model_update = (
self._create_base_type_volume(opts, volume, volume_type))
@ -821,23 +810,15 @@ class HuaweiBaseDriver(driver.VolumeDriver):
If the volume exists on the array, return the LUN ID.
If not exists, raise or log warning.
"""
# Firstly, try to find LUN ID by volume.provider_location.
metadata = huawei_utils.get_lun_metadata(volume)
lun_id = metadata.get('huawei_lun_id')
# If LUN ID not recorded, find LUN ID by LUN NAME.
lun_id, lun_wwn = huawei_utils.get_volume_lun_id(self.client, volume)
if not lun_id:
volume_name = huawei_utils.encode_name(volume.id)
lun_id = self.client.get_lun_id_by_name(volume_name)
if not lun_id:
msg = (_("Volume %s does not exist on the array.")
% volume.id)
if action == constants.VOLUME_NOT_EXISTS_WARN:
LOG.warning(msg)
if action == constants.VOLUME_NOT_EXISTS_RAISE:
raise exception.VolumeBackendAPIException(data=msg)
return
msg = _("Volume %s does not exist on the array.") % volume.id
if action == constants.VOLUME_NOT_EXISTS_WARN:
LOG.warning(msg)
if action == constants.VOLUME_NOT_EXISTS_RAISE:
raise exception.VolumeBackendAPIException(data=msg)
return
lun_wwn = metadata.get('huawei_lun_wwn')
if not lun_wwn:
LOG.debug("No LUN WWN recorded for volume %s.", volume.id)
@ -884,12 +865,11 @@ class HuaweiBaseDriver(driver.VolumeDriver):
'newsize': new_size})
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
volume_name = huawei_utils.encode_name(volume.id)
LOG.info(_LI(
'Extend volume: %(volumename)s, '
'oldsize: %(oldsize)s, newsize: %(newsize)s.'),
{'volumename': volume_name,
{'volumename': volume.id,
'oldsize': old_size,
'newsize': new_size})
@ -898,13 +878,12 @@ class HuaweiBaseDriver(driver.VolumeDriver):
def create_snapshot(self, snapshot):
volume = snapshot.volume
if not volume:
msg = (_("Can't get volume id from snapshot, snapshot: %(id)s")
% {"id": snapshot.id})
msg = _("Can't get volume id from snapshot, snapshot: %(id)s"
) % {'id': snapshot.id}
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
volume_name = huawei_utils.encode_name(snapshot.volume_id)
lun_id = self.client.get_lun_id(volume, volume_name)
lun_id, lun_wwn = huawei_utils.get_volume_lun_id(self.client, volume)
snapshot_name = huawei_utils.encode_name(snapshot.id)
snapshot_description = snapshot.id
snapshot_info = self.client.create_snapshot(lun_id,
@ -918,20 +897,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
'lun_info': snapshot_info}
def delete_snapshot(self, snapshot):
snapshotname = huawei_utils.encode_name(snapshot.id)
volume_name = huawei_utils.encode_name(snapshot.volume_id)
LOG.info(_LI(
'stop_snapshot: snapshot name: %(snapshot)s, '
'volume name: %(volume)s.'),
{'snapshot': snapshotname,
'volume': volume_name},)
metadata = huawei_utils.get_snapshot_metadata(snapshot)
snapshot_id = metadata.get('huawei_snapshot_id')
if snapshot_id is None:
snapshot_id = self.client.get_snapshot_id_by_name(snapshotname)
snapshot_id = huawei_utils.get_snapshot_id(self.client, snapshot)
if snapshot_id and self.client.check_snapshot_exist(snapshot_id):
self.client.stop_snapshot(snapshot_id)
self.client.delete_snapshot(snapshot_id)
@ -1203,8 +1169,7 @@ class HuaweiBaseDriver(driver.VolumeDriver):
'replication_type': None,
}
metadata = huawei_utils.get_lun_metadata(volume)
lun_id = metadata['huawei_lun_id']
lun_id, lun_wwn = huawei_utils.get_volume_lun_id(self.client, volume)
old_opts = self.get_lun_specs(lun_id)
new_specs = new_type['extra_specs']
@ -1568,8 +1533,9 @@ class HuaweiBaseDriver(driver.VolumeDriver):
def manage_existing_snapshot(self, snapshot, existing_ref):
snapshot_info = self._get_snapshot_info_by_ref(existing_ref)
snapshot_id = snapshot_info.get('ID')
parent_metadata = huawei_utils.get_lun_metadata(snapshot.volume)
parent_lun_id = parent_metadata.get('huawei_lun_id')
parent_lun_id, lun_wwn = huawei_utils.get_volume_lun_id(
self.client, snapshot.volume)
if parent_lun_id != snapshot_info.get('PARENTID'):
msg = (_("Can't import snapshot %s to Cinder. "
"Snapshot doesn't belong to volume."), snapshot_id)
@ -1683,14 +1649,13 @@ class HuaweiBaseDriver(driver.VolumeDriver):
for snapshot in snapshots:
volume = snapshot.volume
if not volume:
msg = (_("Can't get volume id from snapshot, "
"snapshot: %(id)s") % {"id": snapshot.id})
msg = _("Can't get volume id from snapshot, "
"snapshot: %(id)s") % {'id': snapshot.id}
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
volume_name = huawei_utils.encode_name(volume.id)
lun_id = self.client.get_lun_id(volume, volume_name)
lun_id, lun_wwn = huawei_utils.get_volume_lun_id(
self.client, volume)
snapshot_name = huawei_utils.encode_name(snapshot.id)
snapshot_description = snapshot.id
info = self.client.create_snapshot(lun_id,
@ -1947,10 +1912,7 @@ class HuaweiISCSIDriver(HuaweiBaseDriver, driver.ISCSIDriver):
'portgroup_id': portgroup_id},)
# Create hostgroup if not exist.
original_host_name = connector['host']
host_name = huawei_utils.encode_host_name(original_host_name)
host_id = self.client.add_host_with_check(host_name,
original_host_name)
host_id = self.client.add_host_with_check(connector['host'])
# Add initiator to the host.
self.client.ensure_initiator_added(initiator_name,
@ -2025,8 +1987,7 @@ class HuaweiISCSIDriver(HuaweiBaseDriver, driver.ISCSIDriver):
if portgroup:
portgroup_id = self.client.get_tgt_port_group(portgroup)
host_name = huawei_utils.encode_host_name(host_name)
host_id = self.client.get_host_id_by_name(host_name)
host_id = huawei_utils.get_host_id(self.client, host_name)
if host_id:
mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id
view_id = self.client.find_mapping_view(mapping_view_name)
@ -2138,11 +2099,7 @@ class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
'lun_id': lun_id},)
portg_id = None
original_host_name = connector['host']
host_name = huawei_utils.encode_host_name(original_host_name)
host_id = self.client.add_host_with_check(host_name,
original_host_name)
host_id = self.client.add_host_with_check(connector['host'])
if not self.fcsan:
self.fcsan = fczm_utils.create_lookup_service()
@ -2276,7 +2233,6 @@ class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
"""Delete map between a volume and a host."""
lun_id, lun_type = self.get_lun_id_and_type(volume)
wwns = connector['wwpns']
host_name = connector['host']
left_lunnum = -1
lungroup_id = None
@ -2285,8 +2241,7 @@ class HuaweiFCDriver(HuaweiBaseDriver, driver.FibreChannelDriver):
'LUN ID: %(lun_id)s.'),
{'wwns': wwns, 'lun_id': lun_id})
host_name = huawei_utils.encode_host_name(host_name)
host_id = self.client.get_host_id_by_name(host_name)
host_id = huawei_utils.get_host_id(self.client, host_name)
if host_id:
mapping_view_name = constants.MAPPING_VIEW_PREFIX + host_id
view_id = self.client.find_mapping_view(mapping_view_name)

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import hashlib
import json
import six
import time
@ -29,9 +30,16 @@ from cinder.volume.drivers.huawei import constants
LOG = logging.getLogger(__name__)
def encode_name(name):
pre_name = name.split("-")[0]
vol_encoded = six.text_type(hash(name))
def encode_name(id):
encoded_name = hashlib.md5(id.encode('utf-8')).hexdigest()
prefix = id.split('-')[0] + '-'
postfix = encoded_name[:constants.MAX_NAME_LENGTH - len(prefix)]
return prefix + postfix
def old_encode_name(id):
pre_name = id.split("-")[0]
vol_encoded = six.text_type(hash(id))
if vol_encoded.startswith('-'):
newuuid = pre_name + vol_encoded
else:
@ -40,7 +48,14 @@ def encode_name(name):
def encode_host_name(name):
if name and (len(name) > constants.MAX_HOSTNAME_LENGTH):
if name and len(name) > constants.MAX_NAME_LENGTH:
encoded_name = hashlib.md5(name.encode('utf-8')).hexdigest()
return encoded_name[:constants.MAX_NAME_LENGTH]
return name
def old_encode_host_name(name):
if name and len(name) > constants.MAX_NAME_LENGTH:
name = six.text_type(hash(name))
return name
@ -147,3 +162,50 @@ def get_snapshot_metadata(snapshot):
# To keep compatible with old driver version
return {'huawei_snapshot_id': six.text_type(info)}
def get_volume_lun_id(client, volume):
metadata = get_lun_metadata(volume)
lun_id = metadata.get('huawei_lun_id')
# First try the new encoded way.
if not lun_id:
volume_name = encode_name(volume.id)
lun_id = client.get_lun_id_by_name(volume_name)
# If new encoded way not found, try the old encoded way.
if not lun_id:
volume_name = old_encode_name(volume.id)
lun_id = client.get_lun_id_by_name(volume_name)
return lun_id, metadata.get('huawei_lun_wwn')
def get_snapshot_id(client, snapshot):
metadata = get_snapshot_metadata(snapshot)
snapshot_id = metadata.get('huawei_snapshot_id')
# First try the new encoded way.
if not snapshot_id:
name = encode_name(snapshot.id)
snapshot_id = client.get_snapshot_id_by_name(name)
# If new encoded way not found, try the old encoded way.
if not snapshot_id:
name = old_encode_name(snapshot.id)
snapshot_id = client.get_snapshot_id_by_name(name)
return snapshot_id
def get_host_id(client, host_name):
encoded_name = encode_host_name(host_name)
host_id = client.get_host_id_by_name(encoded_name)
if encoded_name == host_name:
return host_id
if not host_id:
encoded_name = old_encode_host_name(host_name)
host_id = client.get_host_id_by_name(encoded_name)
return host_id

View File

@ -103,32 +103,24 @@ class HuaweiHyperMetro(object):
def connect_volume_fc(self, volume, connector):
"""Create map between a volume and a host for FC."""
wwns = connector['wwpns']
volume_name = huawei_utils.encode_name(volume.id)
LOG.info(_LI(
'initialize_connection_fc, initiator: %(wwpns)s,'
' volume name: %(volume)s.'),
'initialize_connection_fc, initiator: %(wwpns)s, '
'volume id: %(id)s.'),
{'wwpns': wwns,
'volume': volume_name})
'id': volume.id})
metadata = huawei_utils.get_lun_metadata(volume)
lun_id = metadata['remote_lun_id']
lun_id = metadata.get('remote_lun_id')
if lun_id is None:
lun_id = self.rmt_client.get_lun_id_by_name(volume_name)
if lun_id is None:
msg = _("Can't get volume id. Volume name: %s.") % volume_name
msg = _("Can't get volume id. Volume name: %s.") % volume.id
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
original_host_name = connector['host']
host_name = huawei_utils.encode_host_name(original_host_name)
host_id = self.client.add_host_with_check(host_name,
original_host_name)
host_id = self.client.add_host_with_check(original_host_name)
# Create hostgroup if not exist.
host_id = self.rmt_client.add_host_with_check(
host_name, original_host_name)
host_id = self.rmt_client.add_host_with_check(original_host_name)
online_wwns_in_host = (
self.rmt_client.get_host_online_fc_initiators(host_id))
@ -183,23 +175,21 @@ class HuaweiHyperMetro(object):
def disconnect_volume_fc(self, volume, connector):
"""Delete map between a volume and a host for FC."""
wwns = connector['wwpns']
volume_name = huawei_utils.encode_name(volume.id)
metadata = huawei_utils.get_lun_metadata(volume)
lun_id = metadata['remote_lun_id']
lun_id = metadata.get('remote_lun_id')
host_name = connector['host']
left_lunnum = -1
lungroup_id = None
view_id = None
LOG.info(_LI('terminate_connection_fc: volume name: %(volume)s, '
LOG.info(_LI('terminate_connection_fc: volume: %(id)s, '
'wwpns: %(wwns)s, '
'lun_id: %(lunid)s.'),
{'volume': volume_name,
{'id': volume.id,
'wwns': wwns,
'lunid': lun_id},)
host_name = huawei_utils.encode_host_name(host_name)
hostid = self.rmt_client.get_host_id_by_name(host_name)
hostid = huawei_utils.get_host_id(self.rmt_client, host_name)
if hostid:
mapping_view_name = constants.MAPPING_VIEW_PREFIX + hostid
view_id = self.rmt_client.find_mapping_view(
@ -225,7 +215,7 @@ class HuaweiHyperMetro(object):
(tgt_port_wwns, init_targ_map) = (
self.rmt_client.get_init_targ_map(wwns))
hostid = self.rmt_client.get_host_id_by_name(host_name)
hostid = huawei_utils.get_host_id(self.rmt_client, host_name)
if hostid:
mapping_view_name = constants.MAPPING_VIEW_PREFIX + hostid
view_id = self.rmt_client.find_mapping_view(
@ -348,10 +338,18 @@ class HuaweiHyperMetro(object):
return metro_id
def check_consistencygroup_need_to_stop(self, group):
group_name = huawei_utils.encode_name(group.id)
def _get_metro_group_id(self, id):
group_name = huawei_utils.encode_name(id)
metrogroup_id = self.client.get_metrogroup_by_name(group_name)
if not metrogroup_id:
group_name = huawei_utils.old_encode_name(id)
metrogroup_id = self.client.get_metrogroup_by_name(group_name)
return metrogroup_id
def check_consistencygroup_need_to_stop(self, group):
metrogroup_id = self._get_metro_group_id(group.id)
if metrogroup_id:
metrogroup_info = self.client.get_metrogroup_by_id(metrogroup_id)
health_status = metrogroup_info['HEALTHSTATUS']

View File

@ -297,7 +297,8 @@ class RestClient(object):
result = self.call(url, None, "GET")
self._assert_rest_result(result, _('Get lun id by name error.'))
return self._get_id_from_result(result, name, 'NAME')
if 'data' in result and result['data']:
return result['data'][0]['ID']
def activate_snapshot(self, snapshot_id):
url = "/snapshot/activate"
@ -322,19 +323,6 @@ class RestClient(object):
return result['data']
def get_lun_id(self, volume, volume_name):
metadata = huawei_utils.get_lun_metadata(volume)
lun_id = (metadata.get('huawei_lun_id') or
self.get_lun_id_by_name(volume_name))
if not lun_id:
msg = (_("Can't find lun info on the array. "
"volume: %(id)s, lun name: %(name)s.") %
{'id': volume.id, 'name': volume_name})
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
return lun_id
def check_snapshot_exist(self, snapshot_id):
url = "/snapshot/%s" % snapshot_id
result = self.call(url, None, "GET")
@ -368,7 +356,8 @@ class RestClient(object):
return
self._assert_rest_result(result, _('Get snapshot id error.'))
return self._get_id_from_result(result, name, 'NAME')
if 'data' in result and result['data']:
return result['data'][0]['ID']
def create_luncopy(self, luncopyname, srclunid, tgtlunid):
"""Create a luncopy."""
@ -646,46 +635,41 @@ class RestClient(object):
def get_host_id_by_name(self, host_name):
"""Get the given host ID."""
url = "/host?range=[0-65535]"
url = "/host?filter=NAME::%s" % host_name
result = self.call(url, None, "GET")
self._assert_rest_result(result, _('Find host in hostgroup error.'))
return self._get_id_from_result(result, host_name, 'NAME')
if 'data' in result and result['data']:
return result['data'][0]['ID']
def add_host_with_check(self, host_name, host_name_before_hash):
host_id = self.get_host_id_by_name(host_name)
def add_host_with_check(self, host_name):
host_id = huawei_utils.get_host_id(self, host_name)
if host_id:
LOG.info(_LI(
'add_host_with_check. '
'host name: %(name)s, '
'host id: %(id)s'),
{'name': host_name,
'id': host_id})
LOG.info(_LI('Got exist host. 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(_LI(
'Failed to create host: %(name)s. '
'Check if it exists on the array.'),
{'name': host_name})
host_id = self.get_host_id_by_name(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 exception.VolumeBackendAPIException(data=err_msg)
encoded_name = huawei_utils.encode_host_name(host_name)
LOG.info(_LI(
'add_host_with_check. '
'create host success. '
'host name: %(name)s, '
'host id: %(id)s'),
{'name': host_name,
'id': host_id})
try:
host_id = self._add_host(encoded_name, host_name)
except Exception:
LOG.info(_LI('Failed to create host %s, check if already exist.'),
encoded_name)
host_id = self.get_host_id_by_name(encoded_name)
if not host_id:
msg = _('Failed to create host: %(name)s. '
'Please check if it exists on the array.'
) % {'name': encoded_name}
LOG.error(msg)
raise exception.VolumeBackendAPIException(data=msg)
LOG.info(_LI('create host success. host name: %(name)s, '
'host id: %(id)s'),
{'name': encoded_name,
'id': host_id})
return host_id
def _add_host(self, hostname, host_name_before_hash):