fddb9b7962
The LVM driver is reporting incorrect target_portal and target_portals entries for IPv6 with all the targets, as it is not enclosing the address in square brackets making it impossible for iscsiadm in OS-Brick to tell the port appart from the IP address. This patch makes sure that IPv6 addresses in target_portal and target_portals are properly formatted in the [IPv6_address]:port when the IPv6_address does not already include the square brackets. This fix affects all the targets: IET, LIO, TGT, CXT, and SCST. Closes-Bug: #1696866 Change-Id: Ie7053c813af8c99b5545222d4724b71061348a09
247 lines
11 KiB
Python
247 lines
11 KiB
Python
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import mock
|
|
|
|
from cinder import context
|
|
from cinder.tests.unit.targets import targets_fixture as tf
|
|
from cinder import utils
|
|
from cinder.volume.targets import scst
|
|
from cinder.volume import utils as vutils
|
|
|
|
|
|
class TestSCSTAdmDriver(tf.TargetDriverFixture):
|
|
|
|
def setUp(self):
|
|
super(TestSCSTAdmDriver, self).setUp()
|
|
self.target = scst.SCSTAdm(root_helper=utils.get_root_helper(),
|
|
configuration=self.configuration)
|
|
|
|
self.fake_iscsi_scan = \
|
|
('Collecting current configuration: done.\n'
|
|
'Driver Target\n'
|
|
'----------------------------------------------\n'
|
|
'iscsi iqn.2010-10.org.openstack:'
|
|
'volume-ed2c2222-5fc0-11e4-aa15-123b93f75cba\n'
|
|
'All done.\n')
|
|
|
|
self.fake_iscsi_attribute_scan = \
|
|
('Collecting current configuration: done.\n'
|
|
'Attribute Value Writable KEY\n'
|
|
'------------------------------------------\n'
|
|
'rel_tgt_id 1 Yes Yes\n'
|
|
'Dynamic attributes available\n'
|
|
'----------------------------\n'
|
|
'IncomingUser\n'
|
|
'OutgoingUser\n'
|
|
'allowed_portal\n'
|
|
'LUN CREATE attributes available\n'
|
|
'-------------------------------\n'
|
|
'read_only\n'
|
|
'All done.\n')
|
|
self.fake_list_group = \
|
|
('org.openstack:volume-vedams\n'
|
|
'Collecting current configuration: done.\n'
|
|
'Driver: iscsi\n'
|
|
'Target: iqn.2010-10.org.openstack:volume-vedams\n'
|
|
'Driver/target \'iscsi/iqn.2010-10.org.openstack:volume-vedams\''
|
|
'has no associated LUNs.\n'
|
|
'Group: iqn.1993-08.org.debian:01:626bf14ebdc\n'
|
|
'Assigned LUNs:\n'
|
|
'LUN Device\n'
|
|
'------------------\n'
|
|
'1 1b67387810256\n'
|
|
'2 2a0f1cc9cd595\n'
|
|
'Assigned Initiators:\n'
|
|
'Initiator\n'
|
|
'-------------------------------------\n'
|
|
'iqn.1993-08.org.debian:01:626bf14ebdc\n'
|
|
'All done.\n')
|
|
|
|
self.target.db = mock.MagicMock(
|
|
volume_get=lambda x, y: {'provider_auth': 'IncomingUser foo bar'})
|
|
|
|
@mock.patch.object(utils, 'execute')
|
|
@mock.patch.object(scst.SCSTAdm, '_target_attribute')
|
|
@mock.patch.object(scst.SCSTAdm, 'scst_execute')
|
|
def test_get_target(self, mock_execute,
|
|
mock_target_attribute,
|
|
mock_scst_execute):
|
|
mock_target_attribute.return_value = 1
|
|
mock_execute.return_value = (self.fake_iscsi_scan, None)
|
|
expected = 1
|
|
self.assertEqual(expected, self.target._get_target(
|
|
'iqn.2010-10.org.openstack:'
|
|
'volume-ed2c2222-5fc0-11e4-aa15-123b93f75cba'))
|
|
|
|
@mock.patch('cinder.privsep.targets.scst.run_scstadmin')
|
|
def test_target_attribute(self, mock_privsep):
|
|
mock_privsep.return_value = (self.fake_iscsi_attribute_scan, None)
|
|
self.assertEqual(str(1), self.target._target_attribute(
|
|
'iqn.2010-10.org.openstack:'
|
|
'volume-ed2c2222-5fc0-11e4-aa15-123b93f75cba'))
|
|
|
|
def test_single_lun_get_target_and_lun(self):
|
|
ctxt = context.get_admin_context()
|
|
self.assertEqual((0, 1), self.target._get_target_and_lun(
|
|
ctxt, self.testvol))
|
|
|
|
@mock.patch.object(utils, 'execute')
|
|
@mock.patch.object(scst.SCSTAdm, '_get_group')
|
|
@mock.patch.object(scst.SCSTAdm, 'scst_execute')
|
|
def test_multi_lun_get_target_and_lun(self, mock_execute, mock_get_group,
|
|
mock_scst_execute):
|
|
mock_execute.return_value = (self.fake_list_group, None)
|
|
mock_get_group.return_value = self.fake_list_group
|
|
|
|
ctxt = context.get_admin_context()
|
|
with mock.patch.object(self.target, 'target_name',
|
|
return_value='iqn.2010-10.org.openstack:'
|
|
'volume-vedams'):
|
|
self.assertEqual((0, 3), self.target._get_target_and_lun(
|
|
ctxt, self.testvol))
|
|
|
|
@mock.patch.object(utils, 'execute')
|
|
@mock.patch.object(scst.SCSTAdm, '_get_target')
|
|
@mock.patch.object(scst.SCSTAdm, 'scst_execute')
|
|
def test_create_iscsi_target(self, mock_execute, mock_get_target,
|
|
mock_scst_execute):
|
|
mock_execute.return_value = (None, None)
|
|
mock_get_target.return_value = 1
|
|
|
|
self.assertEqual(1,
|
|
self.target.create_iscsi_target(
|
|
'iqn.2010-10.org.openstack:'
|
|
'volume-ed2c2222-5fc0-11e4-aa15-123b93f75cba',
|
|
'vol1',
|
|
0, 1, self.fake_volumes_dir))
|
|
|
|
@mock.patch.object(utils, 'execute')
|
|
@mock.patch.object(scst.SCSTAdm, '_get_target')
|
|
@mock.patch.object(scst.SCSTAdm, 'scst_execute')
|
|
def test_create_export(self, mock_execute,
|
|
mock_get_target,
|
|
mock_scst_execute):
|
|
mock_execute.return_value = (None, None)
|
|
mock_scst_execute.return_value = (None, None)
|
|
mock_get_target.return_value = 1
|
|
|
|
def _fake_get_target_and_lun(*args, **kwargs):
|
|
return 0, 1
|
|
|
|
def _fake_iscsi_location(*args, **kwargs):
|
|
return '10.9.8.7:3260,1 iqn.2010-10.org.openstack:' \
|
|
'volume-ed2c2222-5fc0-11e4-aa15-123b93f75cba 1'
|
|
|
|
def _fake_get_target_chap_auth(*args, **kwargs):
|
|
return ('QZJbisGmn9AL954FNF4D', 'P68eE7u9eFqDGexd28DQ')
|
|
|
|
ctxt = context.get_admin_context()
|
|
expected_result = {'location': '10.9.8.7:3260,1 '
|
|
'iqn.2010-10.org.openstack:'
|
|
'volume-ed2c2222-5fc0-11e4-aa15-123b93f75cba 1',
|
|
'auth': 'CHAP '
|
|
'QZJbisGmn9AL954FNF4D P68eE7u9eFqDGexd28DQ'}
|
|
|
|
with mock.patch.object(self.target, '_get_target_and_lun',
|
|
side_effect=_fake_get_target_and_lun),\
|
|
mock.patch.object(self.target, '_get_target_chap_auth',
|
|
side_effect=_fake_get_target_chap_auth),\
|
|
mock.patch.object(self.target, 'initiator_iqn',
|
|
return_value='iqn.1993-08.org.debian:'
|
|
'01:626bf14ebdc'),\
|
|
mock.patch.object(self.target, '_iscsi_location',
|
|
side_effect=_fake_iscsi_location),\
|
|
mock.patch.object(self.target, 'target_driver',
|
|
return_value='iscsi'),\
|
|
mock.patch.object(vutils, 'generate_username',
|
|
side_effect=lambda: 'QZJbisGmn9AL954FNF4D'),\
|
|
mock.patch.object(vutils, 'generate_password',
|
|
side_effect=lambda: 'P68eE7u9eFqDGexd28DQ'):
|
|
self.assertEqual(expected_result,
|
|
self.target.create_export(ctxt,
|
|
self.testvol,
|
|
self.fake_volumes_dir))
|
|
|
|
@mock.patch('cinder.utils.execute')
|
|
@mock.patch.object(scst.SCSTAdm, '_get_target')
|
|
@mock.patch.object(scst.SCSTAdm, 'scst_execute')
|
|
def test_ensure_export(self, mock_execute,
|
|
mock_get_target,
|
|
mock_scst_execute):
|
|
mock_execute.return_value = (None, None)
|
|
mock_scst_execute.return_value = (None, None)
|
|
mock_get_target.return_value = 1
|
|
ctxt = context.get_admin_context()
|
|
|
|
def _fake_get_target_and_lun(*args, **kwargs):
|
|
return 0, 1
|
|
|
|
def _fake_get_target_chap_auth(*args, **kwargs):
|
|
return ('QZJbisGmn9AL954FNF4D', 'P68eE7u9eFqDGexd28DQ')
|
|
|
|
with mock.patch.object(self.target, 'create_iscsi_target'),\
|
|
mock.patch.object(self.target, '_get_target_chap_auth',
|
|
side_effect=_fake_get_target_chap_auth),\
|
|
mock.patch.object(self.target, '_get_target_and_lun',
|
|
side_effect=_fake_get_target_and_lun):
|
|
self.target.ensure_export(ctxt,
|
|
self.testvol,
|
|
self.fake_volumes_dir)
|
|
self.target.create_iscsi_target.assert_called_once_with(
|
|
'iqn.2010-10.org.openstack:testvol',
|
|
'ed2c2222-5fc0-11e4-aa15-123b93f75cba',
|
|
0, 1, self.fake_volumes_dir, _fake_get_target_chap_auth())
|
|
|
|
@mock.patch('cinder.utils.execute')
|
|
@mock.patch.object(scst.SCSTAdm, '_get_target')
|
|
@mock.patch.object(scst.SCSTAdm, 'scst_execute')
|
|
def test_ensure_export_chap(self, mock_execute,
|
|
mock_get_target,
|
|
mock_scst_execute):
|
|
mock_execute.return_value = (None, None)
|
|
mock_scst_execute.return_value = (None, None)
|
|
mock_get_target.return_value = 1
|
|
ctxt = context.get_admin_context()
|
|
|
|
def _fake_get_target_and_lun(*args, **kwargs):
|
|
return 0, 1
|
|
|
|
def _fake_get_target_chap_auth(*args, **kwargs):
|
|
return None
|
|
|
|
with mock.patch.object(self.target, 'create_iscsi_target'),\
|
|
mock.patch.object(self.target, '_get_target_chap_auth',
|
|
side_effect=_fake_get_target_chap_auth),\
|
|
mock.patch.object(self.target, '_get_target_and_lun',
|
|
side_effect=_fake_get_target_and_lun):
|
|
self.target.ensure_export(ctxt,
|
|
self.testvol,
|
|
self.fake_volumes_dir)
|
|
self.target.create_iscsi_target.assert_called_once_with(
|
|
'iqn.2010-10.org.openstack:testvol',
|
|
'ed2c2222-5fc0-11e4-aa15-123b93f75cba',
|
|
0, 1, self.fake_volumes_dir, None)
|
|
|
|
def test_iscsi_location(self):
|
|
location = self.target._iscsi_location('portal', 1, 'target', 2)
|
|
self.assertEqual('portal:3260,1 target 2', location)
|
|
|
|
def test_iscsi_location_IPv6(self):
|
|
ip = 'fd00:fd00:fd00:3000::12'
|
|
location = self.target._iscsi_location(ip, 1, 'target', 2)
|
|
self.assertEqual('[%s]:3260,1 target 2' % ip, location)
|
|
|
|
ip = '[' + ip + ']'
|
|
location = self.target._iscsi_location(ip, 1, 'target', 2)
|
|
self.assertEqual(ip + ':3260,1 target 2', location)
|