Huawei driver refactor(1/10)
Huawei driver code is terribly decayed and hard to maintain. From this patch on, we'll try to progressively refactor total Huawei driver, make the code more clear, reliable and maintainable. This patch mainly optimized the huawei_conf.py file and the logic that according to it. Change-Id: I5da3e2a8b1bae4502ae4025a931e9c6899c81e56
This commit is contained in:
parent
1c0224d901
commit
45caa24e1b
@ -2110,28 +2110,33 @@ class FakeHuaweiConf(huawei_conf.HuaweiConf):
|
||||
setattr(self.conf, 'metro_san_password', 'Admin@storage1')
|
||||
setattr(self.conf, 'metro_domain_name', 'hypermetro_test')
|
||||
|
||||
iscsi_info = {'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'TargetIP': '192.0.2.2',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
'TargetPortGroup': 'portgroup-test', }
|
||||
setattr(self.conf, 'iscsi_info', [iscsi_info])
|
||||
iscsi_info = {
|
||||
'default_target_ips': '192.0.2.2',
|
||||
'initiators': {
|
||||
'iqn.1993-08.debian:01:ec2bff7ac3a3': {
|
||||
'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
'TargetPortGroup': 'portgroup-test',
|
||||
}
|
||||
}
|
||||
}
|
||||
setattr(self.conf, 'iscsi_info', iscsi_info)
|
||||
|
||||
rmt_iscsi_info = ('{ Name: iqn.1993-08.debian:01:ec2bff7acxxx;\n'
|
||||
'TargetIP:1.1.1.1;CHAPinfo:mm-user#mm-user@storage;'
|
||||
'ALUA:1; TargetPortGroup:portgroup-test};\t\n '
|
||||
'{ Name: iqn.1993-08.debian:01:ec2bff7acyyy;\n'
|
||||
'TargetIP:2.2.2.2;CHAPinfo:nn-user#nn-user@storage;'
|
||||
'ALUA:0; TargetPortGroup:portgroup-test1}\t\n')
|
||||
rmt_iscsi_info = {'Name': 'iqn.1993-08.debian:01:ec2bff7acxxx',
|
||||
'TargetIP': '1.1.1.1',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
'TargetPortGroup': 'portgroup-test'}
|
||||
|
||||
targets = [{'backend_id': REPLICA_BACKEND_ID,
|
||||
'storage_pool': 'OpenStack_Pool',
|
||||
'san_address':
|
||||
'https://192.0.2.69:8088/deviceManager/rest/',
|
||||
'san_user': 'admin',
|
||||
'san_password': 'Admin@storage1',
|
||||
'iscsi_info': rmt_iscsi_info}]
|
||||
setattr(self.conf, 'replication_device', targets)
|
||||
target = {'backend_id': REPLICA_BACKEND_ID,
|
||||
'storage_pool': 'OpenStack_Pool',
|
||||
'san_address':
|
||||
'https://192.0.2.69:8088/deviceManager/rest/',
|
||||
'san_user': 'admin',
|
||||
'san_password': 'Admin@storage1',
|
||||
'iscsi_info': rmt_iscsi_info}
|
||||
setattr(self.conf, 'replication', target)
|
||||
|
||||
setattr(self.conf, 'safe_get', self.safe_get)
|
||||
|
||||
@ -2545,25 +2550,13 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
||||
self.driver.client.login()
|
||||
|
||||
def test_parse_rmt_iscsi_info(self):
|
||||
rmt_devs = self.driver.huawei_conf.get_replication_devices()
|
||||
iscsi_info = rmt_devs[0]['iscsi_info']
|
||||
expected_iscsi_info = [{'Name': 'iqn.1993-08.debian:01:ec2bff7acxxx',
|
||||
'TargetIP': '1.1.1.1',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
'TargetPortGroup': 'portgroup-test'},
|
||||
{'Name': 'iqn.1993-08.debian:01:ec2bff7acyyy',
|
||||
'TargetIP': '2.2.2.2',
|
||||
'CHAPinfo': 'nn-user;nn-user@storage',
|
||||
'ALUA': '0',
|
||||
'TargetPortGroup': 'portgroup-test1'}]
|
||||
self.assertEqual(expected_iscsi_info, iscsi_info)
|
||||
|
||||
def test_parse_rmt_iscsi_info_without_iscsi_configuration(self):
|
||||
self.configuration.replication_device[0]['iscsi_info'] = ''
|
||||
rmt_devs = self.driver.huawei_conf.get_replication_devices()
|
||||
iscsi_info = rmt_devs[0]['iscsi_info']
|
||||
self.assertEqual([], iscsi_info)
|
||||
rmt_dev = self.driver.configuration.replication
|
||||
expected_iscsi_info = {'Name': 'iqn.1993-08.debian:01:ec2bff7acxxx',
|
||||
'TargetIP': '1.1.1.1',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
'TargetPortGroup': 'portgroup-test'}
|
||||
self.assertDictEqual(expected_iscsi_info, rmt_dev['iscsi_info'])
|
||||
|
||||
def test_login_success(self):
|
||||
device_id = self.driver.client.login()
|
||||
@ -2849,7 +2842,7 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
||||
temp_connector = copy.deepcopy(FakeConnector)
|
||||
temp_connector['multipath'] = True
|
||||
self.mock_object(rest_client.RestClient, 'get_tgt_port_group',
|
||||
return_value = '11')
|
||||
return_value='11')
|
||||
iscsi_properties = self.driver.initialize_connection(self.volume,
|
||||
temp_connector)
|
||||
self.assertEqual([1, 1], iscsi_properties['data']['target_luns'])
|
||||
@ -2858,22 +2851,28 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
||||
temp_connector = copy.deepcopy(FakeConnector)
|
||||
temp_connector['multipath'] = True
|
||||
self.mock_object(rest_client.RestClient, 'get_tgt_port_group',
|
||||
return_value = '12')
|
||||
return_value='12')
|
||||
self.mock_object(rest_client.RestClient, '_get_tgt_ip_from_portgroup',
|
||||
return_value = [])
|
||||
return_value=[])
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
self.driver.initialize_connection,
|
||||
self.volume, temp_connector)
|
||||
|
||||
def test_initialize_connection_success_multipath_targetip(self):
|
||||
iscsi_info = [{'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'TargetIP': '192.0.2.2',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1'}]
|
||||
iscsi_info = {
|
||||
'initiators': {
|
||||
'iqn.1993-08.debian:01:ec2bff7ac3a3': {
|
||||
'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'TargetIP': '192.0.2.2',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configuration = mock.Mock(spec = conf.Configuration)
|
||||
configuration = mock.Mock(spec=conf.Configuration)
|
||||
configuration.hypermetro_devices = hypermetro_devices
|
||||
driver = FakeISCSIStorage(configuration = self.configuration)
|
||||
driver = FakeISCSIStorage(configuration=self.configuration)
|
||||
driver.do_setup()
|
||||
driver.configuration.iscsi_info = iscsi_info
|
||||
driver.client.iscsi_info = iscsi_info
|
||||
@ -2884,14 +2883,20 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
||||
self.assertEqual([1], iscsi_properties['data']['target_luns'])
|
||||
|
||||
def test_initialize_connection_fail_multipath_targetip(self):
|
||||
iscsi_info = [{'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'TargetIP': '192.0.2.6',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1'}]
|
||||
iscsi_info = {
|
||||
'initiators': {
|
||||
'iqn.1993-08.debian:01:ec2bff7ac3a3': {
|
||||
'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'TargetIP': '192.0.2.6',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configuration = mock.Mock(spec = conf.Configuration)
|
||||
configuration = mock.Mock(spec=conf.Configuration)
|
||||
configuration.hypermetro_devices = hypermetro_devices
|
||||
driver = FakeISCSIStorage(configuration = self.configuration)
|
||||
driver = FakeISCSIStorage(configuration=self.configuration)
|
||||
driver.do_setup()
|
||||
driver.configuration.iscsi_info = iscsi_info
|
||||
driver.client.iscsi_info = iscsi_info
|
||||
@ -2902,18 +2907,23 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
||||
self.volume, temp_connector)
|
||||
|
||||
def test_initialize_connection_success_multipath_defaultip(self):
|
||||
iscsi_info = [{'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1'}]
|
||||
default_target_ip = ['192.0.2.2']
|
||||
configuration = mock.Mock(spec = conf.Configuration)
|
||||
iscsi_info = {
|
||||
'default_target_ips': ['192.0.2.2'],
|
||||
'initiators': {
|
||||
'iqn.1993-08.debian:01:ec2bff7ac3a3': {
|
||||
'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configuration = mock.Mock(spec=conf.Configuration)
|
||||
configuration.hypermetro_devices = hypermetro_devices
|
||||
driver = FakeISCSIStorage(configuration = self.configuration)
|
||||
driver = FakeISCSIStorage(configuration=self.configuration)
|
||||
driver.do_setup()
|
||||
driver.configuration.iscsi_info = iscsi_info
|
||||
driver.client.iscsi_info = iscsi_info
|
||||
driver.configuration.iscsi_default_target_ip = default_target_ip
|
||||
driver.client.iscsi_default_target_ip = default_target_ip
|
||||
temp_connector = copy.deepcopy(FakeConnector)
|
||||
temp_connector['multipath'] = True
|
||||
iscsi_properties = driver.initialize_connection(self.volume,
|
||||
@ -2921,19 +2931,23 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
||||
self.assertEqual([1], iscsi_properties['data']['target_luns'])
|
||||
|
||||
def test_initialize_connection_fail_multipath_defaultip(self):
|
||||
iscsi_info = [{'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1'}]
|
||||
iscsi_info = {
|
||||
'default_target_ips': ['192.0.2.6'],
|
||||
'initiators': {
|
||||
'iqn.1993-08.debian:01:ec2bff7ac3a3': {
|
||||
'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
default_target_ip = ['192.0.2.6']
|
||||
configuration = mock.Mock(spec = conf.Configuration)
|
||||
configuration = mock.Mock(spec=conf.Configuration)
|
||||
configuration.hypermetro_devices = hypermetro_devices
|
||||
driver = FakeISCSIStorage(configuration = self.configuration)
|
||||
driver = FakeISCSIStorage(configuration=self.configuration)
|
||||
driver.do_setup()
|
||||
driver.configuration.iscsi_info = iscsi_info
|
||||
driver.client.iscsi_info = iscsi_info
|
||||
driver.configuration.iscsi_default_target_ip = default_target_ip
|
||||
driver.client.iscsi_default_target_ip = default_target_ip
|
||||
temp_connector = copy.deepcopy(FakeConnector)
|
||||
temp_connector['multipath'] = True
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
@ -2952,17 +2966,23 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
||||
self.volume, temp_connector)
|
||||
|
||||
def test_initialize_connection_fail_multipath_no_ip(self):
|
||||
iscsi_info = [{'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1'}]
|
||||
configuration = mock.Mock(spec = conf.Configuration)
|
||||
iscsi_info = {
|
||||
'default_target_ips': [],
|
||||
'initiators': {
|
||||
'iqn.1993-08.debian:01:ec2bff7ac3a3': {
|
||||
'Name': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
'ALUA': '1',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configuration = mock.Mock(spec=conf.Configuration)
|
||||
configuration.hypermetro_devices = hypermetro_devices
|
||||
driver = FakeISCSIStorage(configuration = self.configuration)
|
||||
driver = FakeISCSIStorage(configuration=self.configuration)
|
||||
driver.do_setup()
|
||||
driver.configuration.iscsi_info = iscsi_info
|
||||
driver.client.iscsi_info = iscsi_info
|
||||
driver.configuration.iscsi_default_target_ip = None
|
||||
driver.client.iscsi_default_target_ip = None
|
||||
temp_connector = copy.deepcopy(FakeConnector)
|
||||
temp_connector['multipath'] = True
|
||||
self.assertRaises(exception.VolumeBackendAPIException,
|
||||
@ -3082,25 +3102,31 @@ class HuaweiISCSIDriverTestCase(HuaweiTestBase):
|
||||
self.assertEqual(self.target_ips, target_ip)
|
||||
|
||||
def test_find_chap_info(self):
|
||||
tmp_dict = {}
|
||||
tmp_dict['Name'] = 'iqn.1993-08.debian:01:ec2bff7ac3a3'
|
||||
tmp_dict['CHAPinfo'] = 'mm-user;mm-user@storage'
|
||||
iscsi_info = [tmp_dict]
|
||||
initiator_name = FakeConnector['initiator']
|
||||
chapinfo = self.driver.client.find_chap_info(iscsi_info,
|
||||
initiator_name)
|
||||
iscsi_info = {
|
||||
'initiators': {
|
||||
'fake.iqn': {
|
||||
'Name': 'fake.iqn',
|
||||
'CHAPinfo': 'mm-user;mm-user@storage',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chapinfo = self.driver.client.find_chap_info(iscsi_info, 'fake.iqn')
|
||||
chap_username, chap_password = chapinfo.split(';')
|
||||
self.assertEqual('mm-user', chap_username)
|
||||
self.assertEqual('mm-user@storage', chap_password)
|
||||
|
||||
def test_find_alua_info(self):
|
||||
tmp_dict = {}
|
||||
tmp_dict['Name'] = 'iqn.1993-08.debian:01:ec2bff7ac3a3'
|
||||
tmp_dict['ALUA'] = '1'
|
||||
iscsi_info = [tmp_dict]
|
||||
initiator_name = FakeConnector['initiator']
|
||||
type = self.driver.client._find_alua_info(iscsi_info,
|
||||
initiator_name)
|
||||
iscsi_info = {
|
||||
'initiators': {
|
||||
'fake.iqn': {
|
||||
'Name': 'fake.iqn',
|
||||
'ALUA': '1',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type = self.driver.client._find_alua_info(iscsi_info, 'fake.iqn')
|
||||
self.assertEqual('1', type)
|
||||
|
||||
def test_get_pool_info(self):
|
||||
@ -5630,11 +5656,7 @@ class HuaweiConfTestCase(test.TestCase):
|
||||
'san_user': 'admin',
|
||||
'san_password': '123456',
|
||||
'storage_pool': 'OpenStack_Pool',
|
||||
'iscsi_info': """{Name:iqn.1993-08.debian:01:ec2bff7acxxx;
|
||||
TargetIP:1.1.1.1;
|
||||
CHAPinfo:mm-user@storage;
|
||||
ALUA:1;
|
||||
TargetPortGroup:portgroup-test}"""
|
||||
'iscsi_info': '{Name:iqn;CHAPinfo:user#pwd;ALUA:1}'
|
||||
}]
|
||||
)
|
||||
def test_get_replication_devices(self, config):
|
||||
@ -5643,21 +5665,29 @@ class HuaweiConfTestCase(test.TestCase):
|
||||
mock.Mock(return_value=config)
|
||||
)
|
||||
|
||||
replication_devices = self.huawei_conf.get_replication_devices()
|
||||
expected = [
|
||||
{'backend_id': 'default',
|
||||
'iscsi_default_target_ip': [],
|
||||
'iscsi_info': [{'ALUA': '1',
|
||||
'CHAPinfo': 'mm-user@storage',
|
||||
'Name': 'iqn.1993-08.debian:01:ec2bff7acxxx',
|
||||
'TargetIP': '1.1.1.1',
|
||||
'TargetPortGroup': 'portgroup-test'}],
|
||||
'san_address': ['https://192.0.2.69:8088/deviceManager/rest/'],
|
||||
'san_password': '123456',
|
||||
'san_user': 'admin',
|
||||
'storage_pools': ['OpenStack_Pool']}]
|
||||
self.huawei_conf._replication_devices(None)
|
||||
expected = {
|
||||
'backend_id': 'default',
|
||||
'san_address': ['https://192.0.2.69:8088/deviceManager/rest/'],
|
||||
'san_password': '123456',
|
||||
'san_user': 'admin',
|
||||
'storage_pools': ['OpenStack_Pool'],
|
||||
'vstore_name': None,
|
||||
'iscsi_info': {
|
||||
'initiators': {
|
||||
'iqn': {'ALUA': '1',
|
||||
'CHAPinfo': 'user;pwd',
|
||||
'Name': 'iqn'}
|
||||
},
|
||||
'default_target_ips': [],
|
||||
},
|
||||
'fc_info': {
|
||||
'initiators': {},
|
||||
'default_target_ips': [],
|
||||
},
|
||||
}
|
||||
|
||||
self.assertEqual(expected, replication_devices)
|
||||
self.assertDictEqual(expected, self.conf.replication)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
|
@ -105,11 +105,16 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
return False
|
||||
|
||||
def get_local_and_remote_dev_conf(self):
|
||||
self.loc_dev_conf = self.huawei_conf.get_local_device()
|
||||
self.loc_dev_conf = {
|
||||
'san_address': self.configuration.san_address,
|
||||
'san_user': self.configuration.san_user,
|
||||
'san_password': self.configuration.san_password,
|
||||
'storage_pools': self.configuration.storage_pools,
|
||||
'iscsi_info': self.configuration.iscsi_info,
|
||||
}
|
||||
|
||||
# Now just support one replication device.
|
||||
replica_devs = self.huawei_conf.get_replication_devices()
|
||||
self.replica_dev_conf = replica_devs[0] if replica_devs else {}
|
||||
self.replica_dev_conf = self.configuration.replication
|
||||
|
||||
def get_local_and_remote_client_conf(self):
|
||||
if self.active_backend_id:
|
||||
@ -310,13 +315,18 @@ class HuaweiBaseDriver(driver.VolumeDriver):
|
||||
'DESCRIPTION': volume.name,
|
||||
'ALLOCTYPE': opts.get('LUNType', self.configuration.lun_type),
|
||||
'CAPACITY': huawei_utils.get_volume_size(volume),
|
||||
'WRITEPOLICY': self.configuration.lun_write_type,
|
||||
'PREFETCHPOLICY': self.configuration.lun_prefetch_type,
|
||||
'PREFETCHVALUE': self.configuration.lun_prefetch_value,
|
||||
'DATATRANSFERPOLICY':
|
||||
opts.get('policy', self.configuration.lun_policy),
|
||||
'READCACHEPOLICY': self.configuration.lun_read_cache_policy,
|
||||
'WRITECACHEPOLICY': self.configuration.lun_write_cache_policy, }
|
||||
'WRITECACHEPOLICY': self.configuration.lun_write_cache_policy,
|
||||
}
|
||||
|
||||
if hasattr(self.configuration, 'write_type'):
|
||||
params['WRITEPOLICY'] = self.configuration.write_type
|
||||
if hasattr(self.configuration, 'prefetch_type'):
|
||||
params['PREFETCHPOLICY'] = self.configuration.prefetch_type
|
||||
if hasattr(self.configuration, 'prefetch_value'):
|
||||
params['PREFETCHVALUE'] = self.configuration.prefetch_value
|
||||
if opts.get('policy'):
|
||||
params['DATATRANSFERPOLICY'] = opts['policy']
|
||||
|
||||
LOG.info('volume: %(volume)s, lun params: %(params)s.',
|
||||
{'volume': volume.id, 'params': params})
|
||||
|
@ -116,6 +116,8 @@ REPLICA_DATA_STATUS_INCOMPLETE = '3'
|
||||
LUN_TYPE_MAP = {'Thick': THICK_LUNTYPE,
|
||||
'Thin': THIN_LUNTYPE}
|
||||
|
||||
VALID_PRODUCT = ('V3', 'V5', '18000', 'Dorado')
|
||||
|
||||
PRODUCT_LUN_TYPE = {
|
||||
'Dorado': 'Thin',
|
||||
}
|
||||
|
@ -22,13 +22,14 @@ and set every property into Configuration object as an attribute.
|
||||
|
||||
import base64
|
||||
from defusedxml import ElementTree as ET
|
||||
import os
|
||||
import re
|
||||
import six
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder import utils
|
||||
from cinder.volume.drivers.huawei import constants
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -37,55 +38,69 @@ LOG = logging.getLogger(__name__)
|
||||
class HuaweiConf(object):
|
||||
def __init__(self, conf):
|
||||
self.conf = conf
|
||||
self.last_modify_time = None
|
||||
|
||||
def _encode_authentication(self):
|
||||
need_encode = False
|
||||
def update_config_value(self):
|
||||
file_time = os.stat(self.conf.cinder_huawei_conf_file).st_mtime
|
||||
if self.last_modify_time == file_time:
|
||||
return
|
||||
|
||||
self.last_modify_time = file_time
|
||||
tree = ET.parse(self.conf.cinder_huawei_conf_file)
|
||||
xml_root = tree.getroot()
|
||||
self._encode_authentication(tree, xml_root)
|
||||
|
||||
attr_funcs = (
|
||||
self._san_address,
|
||||
self._san_user,
|
||||
self._san_password,
|
||||
self._san_vstore,
|
||||
self._san_product,
|
||||
self._ssl_cert_path,
|
||||
self._ssl_cert_verify,
|
||||
self._iscsi_info,
|
||||
self._fc_info,
|
||||
self._hypermetro_devices,
|
||||
self._replication_devices,
|
||||
self._lun_type,
|
||||
self._lun_ready_wait_interval,
|
||||
self._lun_copy_wait_interval,
|
||||
self._lun_timeout,
|
||||
self._lun_write_type,
|
||||
self._lun_prefetch,
|
||||
self._lun_policy,
|
||||
self._lun_read_cache_policy,
|
||||
self._lun_write_cache_policy,
|
||||
self._storage_pools,
|
||||
)
|
||||
|
||||
for f in attr_funcs:
|
||||
f(xml_root)
|
||||
|
||||
def _encode_authentication(self, tree, xml_root):
|
||||
name_node = xml_root.find('Storage/UserName')
|
||||
pwd_node = xml_root.find('Storage/UserPassword')
|
||||
if (name_node is not None
|
||||
and not name_node.text.startswith('!$$$')):
|
||||
name_node.text = '!$$$' + base64.b64encode(name_node.text)
|
||||
vstore_node = xml_root.find('Storage/vStoreName')
|
||||
|
||||
need_encode = False
|
||||
if name_node is not None and not name_node.text.startswith('!$$$'):
|
||||
encoded = base64.b64encode(six.b(name_node.text)).decode()
|
||||
name_node.text = '!$$$' + encoded
|
||||
need_encode = True
|
||||
if (pwd_node is not None
|
||||
and not pwd_node.text.startswith('!$$$')):
|
||||
pwd_node.text = '!$$$' + base64.b64encode(pwd_node.text)
|
||||
|
||||
if pwd_node is not None and not pwd_node.text.startswith('!$$$'):
|
||||
encoded = base64.b64encode(six.b(pwd_node.text)).decode()
|
||||
pwd_node.text = '!$$$' + encoded
|
||||
need_encode = True
|
||||
|
||||
if vstore_node is not None and not vstore_node.text.startswith('!$$$'):
|
||||
encoded = base64.b64encode(six.b(vstore_node.text)).decode()
|
||||
vstore_node.text = '!$$$' + encoded
|
||||
need_encode = True
|
||||
|
||||
if need_encode:
|
||||
utils.execute('chmod',
|
||||
'600',
|
||||
self.conf.cinder_huawei_conf_file,
|
||||
run_as_root=True)
|
||||
tree.write(self.conf.cinder_huawei_conf_file, 'UTF-8')
|
||||
|
||||
def update_config_value(self):
|
||||
self._encode_authentication()
|
||||
|
||||
set_attr_funcs = (self._san_address,
|
||||
self._san_user,
|
||||
self._san_password,
|
||||
self._san_product,
|
||||
self._san_protocol,
|
||||
self._lun_type,
|
||||
self._lun_ready_wait_interval,
|
||||
self._lun_copy_wait_interval,
|
||||
self._lun_timeout,
|
||||
self._lun_write_type,
|
||||
self._lun_prefetch,
|
||||
self._lun_policy,
|
||||
self._lun_read_cache_policy,
|
||||
self._lun_write_cache_policy,
|
||||
self._storage_pools,
|
||||
self._iscsi_default_target_ip,
|
||||
self._iscsi_info,)
|
||||
|
||||
tree = ET.parse(self.conf.cinder_huawei_conf_file)
|
||||
xml_root = tree.getroot()
|
||||
for f in set_attr_funcs:
|
||||
f(xml_root)
|
||||
|
||||
def _san_address(self, xml_root):
|
||||
text = xml_root.findtext('Storage/RestURL')
|
||||
if not text:
|
||||
@ -93,8 +108,7 @@ class HuaweiConf(object):
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
addrs = text.split(';')
|
||||
addrs = list(set([x.strip() for x in addrs if x.strip()]))
|
||||
addrs = list(set([x.strip() for x in text.split(';') if x.strip()]))
|
||||
setattr(self.conf, 'san_address', addrs)
|
||||
|
||||
def _san_user(self, xml_root):
|
||||
@ -104,7 +118,7 @@ class HuaweiConf(object):
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
user = base64.b64decode(text[4:])
|
||||
user = base64.b64decode(six.b(text[4:])).decode()
|
||||
setattr(self.conf, 'san_user', user)
|
||||
|
||||
def _san_password(self, xml_root):
|
||||
@ -114,9 +128,52 @@ class HuaweiConf(object):
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
pwd = base64.b64decode(text[4:])
|
||||
pwd = base64.b64decode(six.b(text[4:])).decode()
|
||||
setattr(self.conf, 'san_password', pwd)
|
||||
|
||||
def _san_vstore(self, xml_root):
|
||||
vstore = None
|
||||
text = xml_root.findtext('Storage/vStoreName')
|
||||
if text:
|
||||
vstore = base64.b64decode(six.b(text[4:])).decode()
|
||||
setattr(self.conf, 'vstore_name', vstore)
|
||||
|
||||
def _ssl_cert_path(self, xml_root):
|
||||
text = xml_root.findtext('Storage/SSLCertPath')
|
||||
setattr(self.conf, 'ssl_cert_path', text)
|
||||
|
||||
def _ssl_cert_verify(self, xml_root):
|
||||
value = False
|
||||
text = xml_root.findtext('Storage/SSLCertVerify')
|
||||
if text:
|
||||
if text.lower() in ('true', 'false'):
|
||||
value = text.lower() == 'true'
|
||||
else:
|
||||
msg = _("SSLCertVerify configured error.")
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
setattr(self.conf, 'ssl_cert_verify', value)
|
||||
|
||||
def _set_extra_constants_by_product(self, product):
|
||||
extra_constants = {}
|
||||
if product == 'Dorado':
|
||||
extra_constants['QOS_SPEC_KEYS'] = (
|
||||
'maxIOPS', 'maxBandWidth', 'IOType')
|
||||
extra_constants['QOS_IOTYPES'] = ('2',)
|
||||
extra_constants['SUPPORT_LUN_TYPES'] = ('Thin',)
|
||||
extra_constants['DEFAULT_LUN_TYPE'] = 'Thin'
|
||||
else:
|
||||
extra_constants['QOS_SPEC_KEYS'] = (
|
||||
'maxIOPS', 'minIOPS', 'minBandWidth',
|
||||
'maxBandWidth', 'latency', 'IOType')
|
||||
extra_constants['QOS_IOTYPES'] = ('0', '1', '2')
|
||||
extra_constants['SUPPORT_LUN_TYPES'] = ('Thick', 'Thin')
|
||||
extra_constants['DEFAULT_LUN_TYPE'] = 'Thick'
|
||||
|
||||
for k in extra_constants:
|
||||
setattr(constants, k, extra_constants[k])
|
||||
|
||||
def _san_product(self, xml_root):
|
||||
text = xml_root.findtext('Storage/Product')
|
||||
if not text:
|
||||
@ -125,47 +182,36 @@ class HuaweiConf(object):
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
product = text.strip()
|
||||
setattr(self.conf, 'san_product', product)
|
||||
|
||||
def _san_protocol(self, xml_root):
|
||||
text = xml_root.findtext('Storage/Protocol')
|
||||
if not text:
|
||||
msg = _("SAN protocol is not configured.")
|
||||
if product not in constants.VALID_PRODUCT:
|
||||
msg = _("Invalid SAN product %(text)s, SAN product must be "
|
||||
"in %(valid)s.") % {'text': product,
|
||||
'valid': constants.VALID_PRODUCT}
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
protocol = text.strip()
|
||||
setattr(self.conf, 'san_protocol', protocol)
|
||||
self._set_extra_constants_by_product(product)
|
||||
setattr(self.conf, 'san_product', product)
|
||||
|
||||
def _lun_type(self, xml_root):
|
||||
lun_type = constants.PRODUCT_LUN_TYPE.get(self.conf.san_product,
|
||||
'Thick')
|
||||
|
||||
def _verify_conf_lun_type(lun_type):
|
||||
lun_type = constants.DEFAULT_LUN_TYPE
|
||||
text = xml_root.findtext('LUN/LUNType')
|
||||
if text:
|
||||
lun_type = text.strip()
|
||||
if lun_type not in constants.LUN_TYPE_MAP:
|
||||
msg = _("Invalid lun type %s is configured.") % lun_type
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
if self.conf.san_product in constants.PRODUCT_LUN_TYPE:
|
||||
product_lun_type = constants.PRODUCT_LUN_TYPE[
|
||||
self.conf.san_product]
|
||||
if lun_type != product_lun_type:
|
||||
msg = _("%(array)s array requires %(valid)s lun type, "
|
||||
"but %(conf)s is specified.") % {
|
||||
'array': self.conf.san_product,
|
||||
'valid': product_lun_type,
|
||||
'conf': lun_type}
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
if lun_type not in constants.SUPPORT_LUN_TYPES:
|
||||
msg = _("%(array)s array requires %(valid)s lun type, "
|
||||
"but %(conf)s is specified."
|
||||
) % {'array': self.conf.san_product,
|
||||
'valid': constants.SUPPORT_LUN_TYPES,
|
||||
'conf': lun_type}
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
text = xml_root.findtext('LUN/LUNType')
|
||||
if text:
|
||||
lun_type = text.strip()
|
||||
_verify_conf_lun_type(lun_type)
|
||||
|
||||
lun_type = constants.LUN_TYPE_MAP[lun_type]
|
||||
setattr(self.conf, 'lun_type', lun_type)
|
||||
setattr(self.conf, 'lun_type', constants.LUN_TYPE_MAP[lun_type])
|
||||
|
||||
def _lun_ready_wait_interval(self, xml_root):
|
||||
text = xml_root.findtext('LUN/LUNReadyWaitInterval')
|
||||
@ -184,33 +230,19 @@ class HuaweiConf(object):
|
||||
|
||||
def _lun_write_type(self, xml_root):
|
||||
text = xml_root.findtext('LUN/WriteType')
|
||||
write_type = text.strip() if text else '1'
|
||||
setattr(self.conf, 'lun_write_type', write_type)
|
||||
if text and text.strip():
|
||||
setattr(self.conf, 'write_type', text.strip())
|
||||
|
||||
def _lun_prefetch(self, xml_root):
|
||||
prefetch_type = '3'
|
||||
prefetch_value = '0'
|
||||
|
||||
node = xml_root.find('LUN/Prefetch')
|
||||
if (node is not None
|
||||
and node.attrib['Type']
|
||||
and node.attrib['Value']):
|
||||
prefetch_type = node.attrib['Type'].strip()
|
||||
if prefetch_type not in ['0', '1', '2', '3']:
|
||||
msg = (_(
|
||||
"Invalid prefetch type '%s' is configured. "
|
||||
"PrefetchType must be in 0,1,2,3.") % prefetch_type)
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
if node is not None:
|
||||
if 'Type' in node.attrib:
|
||||
prefetch_type = node.attrib['Type'].strip()
|
||||
setattr(self.conf, 'prefetch_type', prefetch_type)
|
||||
|
||||
prefetch_value = node.attrib['Value'].strip()
|
||||
factor = {'1': 2}
|
||||
factor = int(factor.get(prefetch_type, '1'))
|
||||
prefetch_value = int(prefetch_value) * factor
|
||||
prefetch_value = six.text_type(prefetch_value)
|
||||
|
||||
setattr(self.conf, 'lun_prefetch_type', prefetch_type)
|
||||
setattr(self.conf, 'lun_prefetch_value', prefetch_value)
|
||||
if 'Value' in node.attrib:
|
||||
prefetch_value = node.attrib['Value'].strip()
|
||||
setattr(self.conf, 'prefetch_value', prefetch_value)
|
||||
|
||||
def _lun_policy(self, xml_root):
|
||||
setattr(self.conf, 'lun_policy', '0')
|
||||
@ -222,118 +254,150 @@ class HuaweiConf(object):
|
||||
setattr(self.conf, 'lun_write_cache_policy', '5')
|
||||
|
||||
def _storage_pools(self, xml_root):
|
||||
nodes = xml_root.findall('LUN/StoragePool')
|
||||
if not nodes:
|
||||
text = xml_root.findtext('LUN/StoragePool')
|
||||
if not text:
|
||||
msg = _('Storage pool is not configured.')
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
texts = [x.text for x in nodes]
|
||||
merged_text = ';'.join(texts)
|
||||
pools = set(x.strip() for x in merged_text.split(';') if x.strip())
|
||||
pools = set(x.strip() for x in text.split(';') if x.strip())
|
||||
if not pools:
|
||||
msg = _('Invalid storage pool is configured.')
|
||||
msg = _('No valid storage pool configured.')
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(msg)
|
||||
|
||||
setattr(self.conf, 'storage_pools', list(pools))
|
||||
|
||||
def _iscsi_default_target_ip(self, xml_root):
|
||||
text = xml_root.findtext('iSCSI/DefaultTargetIP')
|
||||
target_ip = text.split() if text else []
|
||||
setattr(self.conf, 'iscsi_default_target_ip', target_ip)
|
||||
|
||||
def _iscsi_info(self, xml_root):
|
||||
iscsi_info = {
|
||||
'default_target_ips': [],
|
||||
'CHAPinfo': xml_root.findtext('iSCSI/CHAPinfo'),
|
||||
'ALUA': xml_root.findtext('iSCSI/ALUA'),
|
||||
'FAILOVERMODE': xml_root.findtext('iSCSI/FAILOVERMODE'),
|
||||
'SPECIALMODETYPE': xml_root.findtext('iSCSI/SPECIALMODETYPE'),
|
||||
'PATHTYPE': xml_root.findtext('iSCSI/PATHTYPE'),
|
||||
}
|
||||
|
||||
text = xml_root.findtext('iSCSI/DefaultTargetIP')
|
||||
if text:
|
||||
iscsi_info['default_target_ips'] = [
|
||||
ip.strip() for ip in text.split(';') if ip.strip()]
|
||||
|
||||
initiators = {}
|
||||
nodes = xml_root.findall('iSCSI/Initiator')
|
||||
if nodes is None:
|
||||
setattr(self.conf, 'iscsi_info', [])
|
||||
return
|
||||
for node in nodes or []:
|
||||
if 'Name' not in node.attrib:
|
||||
msg = _('Name must be specified for initiator.')
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(msg)
|
||||
|
||||
iscsi_info = []
|
||||
for node in nodes:
|
||||
props = {}
|
||||
for item in node.items():
|
||||
props[item[0].strip()] = item[1].strip()
|
||||
|
||||
iscsi_info.append(props)
|
||||
initiators[node.attrib['Name']] = node.attrib
|
||||
|
||||
iscsi_info['initiators'] = initiators
|
||||
setattr(self.conf, 'iscsi_info', iscsi_info)
|
||||
|
||||
def _parse_rmt_iscsi_info(self, iscsi_info):
|
||||
if not (iscsi_info and iscsi_info.strip()):
|
||||
return []
|
||||
|
||||
# Consider iscsi_info value:
|
||||
# ' {Name:xxx ;;TargetPortGroup: xxx};\n'
|
||||
# '{Name:\t\rxxx;CHAPinfo: mm-usr#mm-pwd} '
|
||||
|
||||
# Step 1, ignore whitespace characters, convert to:
|
||||
# '{Name:xxx;;TargetPortGroup:xxx};{Name:xxx;CHAPinfo:mm-usr#mm-pwd}'
|
||||
iscsi_info = ''.join(iscsi_info.split())
|
||||
|
||||
# Step 2, make initiators configure list, convert to:
|
||||
# ['Name:xxx;;TargetPortGroup:xxx', 'Name:xxx;CHAPinfo:mm-usr#mm-pwd']
|
||||
initiator_infos = iscsi_info[1:-1].split('};{')
|
||||
|
||||
# Step 3, get initiator configure pairs, convert to:
|
||||
# [['Name:xxx', '', 'TargetPortGroup:xxx'],
|
||||
# ['Name:xxx', 'CHAPinfo:mm-usr#mm-pwd']]
|
||||
initiator_infos = map(lambda x: x.split(';'), initiator_infos)
|
||||
|
||||
# Step 4, remove invalid configure pairs, convert to:
|
||||
# [['Name:xxx', 'TargetPortGroup:xxx'],
|
||||
# ['Name:xxx', 'CHAPinfo:mm-usr#mm-pwd']]
|
||||
initiator_infos = map(lambda x: [y for y in x if y],
|
||||
initiator_infos)
|
||||
|
||||
# Step 5, make initiators configure dict, convert to:
|
||||
# [{'TargetPortGroup': 'xxx', 'Name': 'xxx'},
|
||||
# {'Name': 'xxx', 'CHAPinfo': 'mm-usr#mm-pwd'}]
|
||||
get_opts = lambda x: x.split(':', 1)
|
||||
initiator_infos = map(lambda x: dict(map(get_opts, x)),
|
||||
initiator_infos)
|
||||
# Convert generator to list for py3 compatibility.
|
||||
initiator_infos = list(initiator_infos)
|
||||
|
||||
# Step 6, replace CHAPinfo 'user#pwd' to 'user;pwd'
|
||||
key = 'CHAPinfo'
|
||||
for info in initiator_infos:
|
||||
if key in info:
|
||||
info[key] = info[key].replace('#', ';', 1)
|
||||
|
||||
return initiator_infos
|
||||
|
||||
def get_replication_devices(self):
|
||||
devs = self.conf.safe_get('replication_device')
|
||||
if not devs:
|
||||
return []
|
||||
|
||||
devs_config = []
|
||||
for dev in devs:
|
||||
dev_config = {}
|
||||
dev_config['backend_id'] = dev['backend_id']
|
||||
dev_config['san_address'] = dev['san_address'].split(';')
|
||||
dev_config['san_user'] = dev['san_user']
|
||||
dev_config['san_password'] = dev['san_password']
|
||||
dev_config['storage_pools'] = dev['storage_pool'].split(';')
|
||||
dev_config['iscsi_info'] = self._parse_rmt_iscsi_info(
|
||||
dev.get('iscsi_info'))
|
||||
dev_config['iscsi_default_target_ip'] = (
|
||||
dev['iscsi_default_target_ip'].split(';')
|
||||
if 'iscsi_default_target_ip' in dev
|
||||
else [])
|
||||
devs_config.append(dev_config)
|
||||
|
||||
return devs_config
|
||||
|
||||
def get_local_device(self):
|
||||
dev_config = {
|
||||
'backend_id': "default",
|
||||
'san_address': self.conf.san_address,
|
||||
'san_user': self.conf.san_user,
|
||||
'san_password': self.conf.san_password,
|
||||
'storage_pools': self.conf.storage_pools,
|
||||
'iscsi_info': self.conf.iscsi_info,
|
||||
'iscsi_default_target_ip': self.conf.iscsi_default_target_ip,
|
||||
def _fc_info(self, xml_root):
|
||||
fc_info = {
|
||||
'ALUA': xml_root.findtext('FC/ALUA'),
|
||||
'FAILOVERMODE': xml_root.findtext('FC/FAILOVERMODE'),
|
||||
'SPECIALMODETYPE': xml_root.findtext('FC/SPECIALMODETYPE'),
|
||||
'PATHTYPE': xml_root.findtext('FC/PATHTYPE'),
|
||||
}
|
||||
return dev_config
|
||||
|
||||
initiators = {}
|
||||
nodes = xml_root.findall('FC/Initiator')
|
||||
for node in nodes or []:
|
||||
if 'Name' not in node.attrib:
|
||||
msg = _('Name must be specified for initiator.')
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(msg)
|
||||
|
||||
initiators[node.attrib['Name']] = node.attrib
|
||||
|
||||
fc_info['initiators'] = initiators
|
||||
setattr(self.conf, 'fc_info', fc_info)
|
||||
|
||||
def _parse_remote_initiator_info(self, dev, ini_type):
|
||||
ini_info = {'default_target_ips': []}
|
||||
|
||||
if dev.get('iscsi_default_target_ip'):
|
||||
ini_info['default_target_ips'] = dev[
|
||||
'iscsi_default_target_ip'].split(';')
|
||||
|
||||
initiators = {}
|
||||
if ini_type in dev:
|
||||
# Analyze initiators configure text, convert to:
|
||||
# [{'Name':'xxx'}, {'Name':'xxx','CHAPinfo':'mm-usr#mm-pwd'}]
|
||||
ini_list = re.split('\s', dev[ini_type])
|
||||
|
||||
def _convert_one_iscsi_info(ini_text):
|
||||
# get initiator configure attr list
|
||||
attr_list = re.split('[{;}]', ini_text)
|
||||
|
||||
# get initiator configures
|
||||
ini = {}
|
||||
for attr in attr_list:
|
||||
if not attr:
|
||||
continue
|
||||
|
||||
pair = attr.split(':', 1)
|
||||
if pair[0] == 'CHAPinfo':
|
||||
value = pair[1].replace('#', ';', 1)
|
||||
else:
|
||||
value = pair[1]
|
||||
ini[pair[0]] = value
|
||||
|
||||
if 'Name' not in ini:
|
||||
msg = _('Name must be specified for initiator.')
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(msg)
|
||||
|
||||
return ini
|
||||
|
||||
for text in ini_list:
|
||||
ini = _convert_one_iscsi_info(text)
|
||||
initiators[ini['Name']] = ini
|
||||
|
||||
ini_info['initiators'] = initiators
|
||||
return ini_info
|
||||
|
||||
def _hypermetro_devices(self, xml_root):
|
||||
dev = self.conf.safe_get('hypermetro_device')
|
||||
config = {}
|
||||
|
||||
if dev:
|
||||
config = {
|
||||
'san_address': dev['san_address'].split(';'),
|
||||
'san_user': dev['san_user'],
|
||||
'san_password': dev['san_password'],
|
||||
'vstore_name': dev.get('vstore_name'),
|
||||
'metro_domain': dev['metro_domain'],
|
||||
'storage_pools': dev['storage_pool'].split(';')[:1],
|
||||
'iscsi_info': self._parse_remote_initiator_info(
|
||||
dev, 'iscsi_info'),
|
||||
'fc_info': self._parse_remote_initiator_info(
|
||||
dev, 'fc_info'),
|
||||
}
|
||||
|
||||
setattr(self.conf, 'hypermetro', config)
|
||||
|
||||
def _replication_devices(self, xml_root):
|
||||
replication_devs = self.conf.safe_get('replication_device')
|
||||
config = {}
|
||||
|
||||
if replication_devs:
|
||||
dev = replication_devs[0]
|
||||
config = {
|
||||
'backend_id': dev['backend_id'],
|
||||
'san_address': dev['san_address'].split(';'),
|
||||
'san_user': dev['san_user'],
|
||||
'san_password': dev['san_password'],
|
||||
'vstore_name': dev.get('vstore_name'),
|
||||
'storage_pools': dev['storage_pool'].split(';')[:1],
|
||||
'iscsi_info': self._parse_remote_initiator_info(
|
||||
dev, 'iscsi_info'),
|
||||
'fc_info': self._parse_remote_initiator_info(
|
||||
dev, 'fc_info'),
|
||||
}
|
||||
|
||||
setattr(self.conf, 'replication', config)
|
||||
|
@ -164,12 +164,9 @@ class HuaweiISCSIDriver(common.HuaweiBaseDriver, driver.ISCSIDriver):
|
||||
portgroup_id = None
|
||||
view_id = None
|
||||
left_lunnum = -1
|
||||
for ini in self.client.iscsi_info:
|
||||
if ini['Name'] == initiator_name:
|
||||
for key in ini:
|
||||
if key == 'TargetPortGroup':
|
||||
portgroup = ini['TargetPortGroup']
|
||||
break
|
||||
ini = self.client.iscsi_info['initiators'].get(initiator_name)
|
||||
if ini and ini.get('TargetPortGroup'):
|
||||
portgroup = ini['TargetPortGroup']
|
||||
|
||||
if portgroup:
|
||||
portgroup_id = self.client.get_tgt_port_group(portgroup)
|
||||
|
@ -410,14 +410,19 @@ class ReplicaPairManager(object):
|
||||
'DESCRIPTION': local_lun_info['DESCRIPTION'],
|
||||
'ALLOCTYPE': local_lun_info['ALLOCTYPE'],
|
||||
'CAPACITY': local_lun_info['CAPACITY'],
|
||||
'WRITEPOLICY': self.conf.lun_write_type,
|
||||
'PREFETCHPOLICY': self.conf.lun_prefetch_type,
|
||||
'PREFETCHVALUE': self.conf.lun_prefetch_value,
|
||||
'DATATRANSFERPOLICY': self.conf.lun_policy,
|
||||
'READCACHEPOLICY': self.conf.lun_read_cache_policy,
|
||||
'WRITECACHEPOLICY': self.conf.lun_write_cache_policy,
|
||||
}
|
||||
|
||||
if 'WRITEPOLICY' in local_lun_info:
|
||||
params['WRITEPOLICY'] = local_lun_info['WRITEPOLICY']
|
||||
if 'PREFETCHPOLICY' in local_lun_info:
|
||||
params['PREFETCHPOLICY'] = local_lun_info['PREFETCHPOLICY']
|
||||
if 'PREFETCHVALUE' in local_lun_info:
|
||||
params['PREFETCHVALUE'] = local_lun_info['PREFETCHVALUE']
|
||||
if 'DATATRANSFERPOLICY' in local_lun_info:
|
||||
params['DATATRANSFERPOLICY'] = local_lun_info['DATATRANSFERPOLICY']
|
||||
|
||||
LOG.debug('Remote lun params: %s.', params)
|
||||
return params
|
||||
|
||||
|
@ -44,9 +44,6 @@ class RestClient(object):
|
||||
self.configuration.storage_pools)
|
||||
self.iscsi_info = kwargs.get('iscsi_info',
|
||||
self.configuration.iscsi_info)
|
||||
self.iscsi_default_target_ip = kwargs.get(
|
||||
'iscsi_default_target_ip',
|
||||
self.configuration.iscsi_default_target_ip)
|
||||
self.session = None
|
||||
self.url = None
|
||||
self.device_id = None
|
||||
@ -828,29 +825,25 @@ class RestClient(object):
|
||||
def find_chap_info(self, iscsi_info, initiator_name):
|
||||
"""Find CHAP info from xml."""
|
||||
chapinfo = None
|
||||
for ini in iscsi_info:
|
||||
if ini['Name'] == initiator_name:
|
||||
if 'CHAPinfo' in ini:
|
||||
chapinfo = ini['CHAPinfo']
|
||||
break
|
||||
|
||||
ini = iscsi_info['initiators'].get(initiator_name)
|
||||
if ini and ini.get('CHAPinfo'):
|
||||
chapinfo = ini['CHAPinfo']
|
||||
return chapinfo
|
||||
|
||||
def _find_alua_info(self, iscsi_info, initiator_name):
|
||||
"""Find ALUA info from xml."""
|
||||
multipath_type = 0
|
||||
for ini in iscsi_info:
|
||||
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 exception.InvalidInput(msg)
|
||||
else:
|
||||
multipath_type = ini['ALUA']
|
||||
break
|
||||
ini = iscsi_info['initiators'].get(initiator_name)
|
||||
if ini and ini.get('ALUA'):
|
||||
if ini['ALUA'] != '1' and ini['ALUA'] != '0':
|
||||
msg = (_(
|
||||
'Invalid ALUA value. '
|
||||
'ALUA value must be 1 or 0.'))
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidInput(msg)
|
||||
else:
|
||||
multipath_type = ini['ALUA']
|
||||
|
||||
return multipath_type
|
||||
|
||||
def _use_chap(self, chapinfo, initiator_name, host_id):
|
||||
@ -1297,9 +1290,10 @@ class RestClient(object):
|
||||
portgroup_id = None
|
||||
|
||||
if multipath:
|
||||
for ini in self.iscsi_info:
|
||||
if ini['Name'] == initiator:
|
||||
portgroup = ini.get('TargetPortGroup')
|
||||
ini = self.iscsi_info['initiators'].get(initiator)
|
||||
if ini and ini.get('TargetPortGroup'):
|
||||
portgroup = ini['TargetPortGroup']
|
||||
|
||||
if portgroup:
|
||||
portgroup_id = self.get_tgt_port_group(portgroup)
|
||||
temp_tgt_ips = self._get_tgt_ip_from_portgroup(portgroup_id)
|
||||
@ -1340,14 +1334,13 @@ class RestClient(object):
|
||||
|
||||
def _get_target_ip(self, initiator):
|
||||
target_ips = []
|
||||
for ini in self.iscsi_info:
|
||||
if ini['Name'] == initiator:
|
||||
if ini.get('TargetIP'):
|
||||
target_ips.append(ini.get('TargetIP'))
|
||||
ini = self.iscsi_info['initiators'].get(initiator)
|
||||
if ini and ini.get('TargetIP'):
|
||||
target_ips.append(ini['TargetIP'])
|
||||
|
||||
# If not specify target IP for some initiators, use default IP.
|
||||
if not target_ips:
|
||||
default_target_ips = self.iscsi_default_target_ip
|
||||
default_target_ips = self.iscsi_info['default_target_ips']
|
||||
if default_target_ips:
|
||||
target_ips.append(default_target_ips[0])
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user