Merge "Huawei driver refactor(1/10)"
This commit is contained in:
commit
45f967ef9a
@ -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…
Reference in New Issue
Block a user