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')
+
self.stubs.Set(self.target,
'_get_target_and_lun',
_fake_get_target_and_lun)
_fake_iscsi_location)
self.stubs.Set(self.target,
'_get_target_chap_auth',
- lambda x: None)
+ _fake_get_target_chap_auth)
self.stubs.Set(self.target,
'target_driver',
'iscsi')
self.testvol_1,
self.fake_volumes_dir))
- def test_ensure_export(self):
+ @mock.patch.object(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')
+
+ self.stubs.Set(self.target,
+ '_get_target_chap_auth',
+ _fake_get_target_chap_auth)
+ self.stubs.Set(self.target,
+ '_get_target_and_lun',
+ _fake_get_target_and_lun)
+
with mock.patch.object(self.target, 'create_iscsi_target'):
self.target.ensure_export(ctxt,
self.testvol_1,
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.object(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
+
+ self.stubs.Set(self.target,
+ '_get_target_chap_auth',
+ _fake_get_target_chap_auth)
+ self.stubs.Set(self.target,
+ '_get_target_and_lun',
+ _fake_get_target_and_lun)
+
+ with mock.patch.object(self.target, 'create_iscsi_target'):
+ self.target.ensure_export(ctxt,
+ self.testvol_1,
+ self.fake_volumes_dir)
self.target.create_iscsi_target.assert_called_once_with(
- 'iqn.2010-10.org.openstack:testvol', 'testvol',
- 1, 0, self.fake_volumes_dir)
+ 'iqn.2010-10.org.openstack:testvol',
+ 'ed2c2222-5fc0-11e4-aa15-123b93f75cba',
+ 0, 1, self.fake_volumes_dir, None)
"SCST target %s"), e)
raise exception.ISCSITargetHelperCommandFailed(
error_mesage="Failed to enable SCST Target.")
+ if chap_auth and self.target_name:
+ try:
+ chap_string = self._iscsi_authentication('IncomingUser=',
+ *chap_auth)
+ (out, _err) = self.scst_execute('-noprompt',
+ '-set_tgt_attr', name,
+ '-driver',
+ self.target_driver,
+ '-attributes',
+ chap_string)
+ LOG.debug("StdOut from scstadmin set target attribute:"
+ " %s.", out)
+ except putils.ProcessExecutionError:
+ msg = _("Failed to set attribute 'Incoming user' for "
+ "SCST target.")
+ LOG.exception(msg)
+ raise exception.ISCSITargetHelperCommandFailed(
+ error_mesage=msg)
if self.target_name:
if self._get_group() is None:
def _get_target_chap_auth(self, context, iscsi_name):
# FIXME(jdg): Need to implement abc method
- pass
+
+ if self._get_target(iscsi_name) is None:
+ return None
+ (out, _err) = self.scst_execute('-list_tgt_attr', iscsi_name,
+ '-driver', self.target_driver)
+ first = "KEY"
+ last = "Dynamic attributes"
+ start = out.index(first) + len(first)
+ end = out.index(last, start)
+ out = out[start:end]
+ out = out.split("\n")[2]
+ if "IncomingUser" in out:
+ out = out.split(" ")
+ out = filter(lambda a: a != "", out)
+ return (out[1], out[2])
+ else:
+ return None
def ensure_export(self, context, volume, volume_path):
- iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
- volume['name'])
- self.create_iscsi_target(iscsi_name, volume['name'], 1, 0, volume_path)
+ iscsi_target, lun = self._get_target_and_lun(context, volume)
+ if self.target_name is None:
+ iscsi_name = "%s%s" % (self.configuration.iscsi_target_prefix,
+ volume['name'])
+ else:
+ iscsi_name = self.target_name
+
+ if self.chap_username and self.chap_password:
+ chap_auth = (self.chap_username, self.chap_password)
+ else:
+ chap_auth = self._get_target_chap_auth(context, iscsi_name)
+
+ self.create_iscsi_target(iscsi_name, volume['id'], iscsi_target,
+ lun, volume_path, chap_auth)
def create_export(self, context, volume, volume_path):
"""Creates an export for a logical volume."""
iscsi_name = self.target_name
if self.chap_username and self.chap_password:
- chap_username = self.chap_username
- chap_password = self.chap_password
+ chap_auth = (self.chap_username, self.chap_password)
else:
- chap_username = vutils.generate_username()
- chap_password = vutils.generate_password()
-
- chap_auth = self._iscsi_authentication('IncomingUser', chap_username,
- chap_password)
+ chap_auth = self._get_target_chap_auth(context, iscsi_name)
+ if not chap_auth:
+ chap_auth = (vutils.generate_username(),
+ vutils.generate_password())
tid = self.create_iscsi_target(iscsi_name, volume['id'], iscsi_target,
lun, volume_path, chap_auth)
self.configuration.iscsi_ip_address, tid, iscsi_name, lun)
LOG.debug('Set provider_location to: %s', data['location'])
data['auth'] = self._iscsi_authentication(
- 'CHAP', chap_username, chap_password)
+ 'CHAP', *chap_auth)
return data
def remove_export(self, context, volume):