Merge "Add ability to zfssa driver to create multiple initiator groups"
This commit is contained in:
commit
2c764a07ac
@ -214,12 +214,17 @@ class FakeZFSSA(object):
|
||||
|
||||
return out
|
||||
|
||||
def get_initiator_initiatorgroup(self, initiator):
|
||||
ret = ['test-init-grp1']
|
||||
return ret
|
||||
|
||||
|
||||
class TestZFSSAISCSIDriver(test.TestCase):
|
||||
|
||||
test_vol = {
|
||||
'name': 'cindervol',
|
||||
'size': 1
|
||||
'size': 1,
|
||||
'id': 1
|
||||
}
|
||||
|
||||
test_snap = {
|
||||
@ -259,6 +264,9 @@ class TestZFSSAISCSIDriver(test.TestCase):
|
||||
'iqn.1-0.org.deb:01:d7, iqn.1-0.org.deb:01:d9'
|
||||
self.configuration.zfssa_initiator_user = ''
|
||||
self.configuration.zfssa_initiator_password = ''
|
||||
self.configuration.zfssa_initiator_config = "{'test-init-grp1':[{'iqn':\
|
||||
'iqn.1-0.org.deb:01:d7','user':'','password':''}],'test-init-grp\
|
||||
2':[{'iqn':'iqn.1-0.org.deb:01:d9','user':'','password':''}]}"
|
||||
self.configuration.zfssa_target_group = 'test-target-grp1'
|
||||
self.configuration.zfssa_target_user = ''
|
||||
self.configuration.zfssa_target_password = ''
|
||||
@ -283,14 +291,20 @@ class TestZFSSAISCSIDriver(test.TestCase):
|
||||
self.test_snap)
|
||||
self.drv.delete_volume(self.test_vol)
|
||||
|
||||
def test_create_export(self):
|
||||
self.drv.create_volume(self.test_vol)
|
||||
self.drv.create_export({}, self.test_vol)
|
||||
self.drv.delete_volume(self.test_vol)
|
||||
|
||||
def test_remove_export(self):
|
||||
self.drv.create_volume(self.test_vol)
|
||||
self.drv.remove_export({}, self.test_vol)
|
||||
self.drv.terminate_connection(self.test_vol, '')
|
||||
self.drv.delete_volume(self.test_vol)
|
||||
|
||||
def test_volume_attach_detach(self):
|
||||
self.drv.create_volume(self.test_vol)
|
||||
|
||||
connector = dict(initiator='iqn.1-0.org.deb:01:d7')
|
||||
props = self.drv.initialize_connection(self.test_vol, connector)
|
||||
self.assertEqual('iscsi', props['driver_volume_type'])
|
||||
self.assertEqual(self.test_vol['id'], props['data']['volume_id'])
|
||||
|
||||
self.drv.terminate_connection(self.test_vol, '')
|
||||
self.drv.delete_volume(self.test_vol)
|
||||
|
||||
def test_get_volume_stats(self):
|
||||
|
@ -14,13 +14,14 @@
|
||||
"""
|
||||
ZFS Storage Appliance Cinder Volume Driver
|
||||
"""
|
||||
import ast
|
||||
import base64
|
||||
|
||||
from oslo.config import cfg
|
||||
from oslo.utils import units
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LE
|
||||
from cinder.i18n import _, _LE, _LW
|
||||
from cinder.openstack.common import log
|
||||
from cinder.volume import driver
|
||||
from cinder.volume.drivers.san import san
|
||||
@ -50,6 +51,8 @@ ZFSSA_OPTS = [
|
||||
help='iSCSI initiator CHAP user.'),
|
||||
cfg.StrOpt('zfssa_initiator_password', default='',
|
||||
help='iSCSI initiator CHAP password.'),
|
||||
cfg.StrOpt('zfssa_initiator_config', default='',
|
||||
help='iSCSI initiators configuration.'),
|
||||
cfg.StrOpt('zfssa_target_group', default='tgt-grp',
|
||||
help='iSCSI target group name.'),
|
||||
cfg.StrOpt('zfssa_target_user', default='',
|
||||
@ -107,30 +110,46 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
||||
compression=lcfg.zfssa_lun_compression,
|
||||
logbias=lcfg.zfssa_lun_logbias)
|
||||
|
||||
if (lcfg.zfssa_initiator != '' and
|
||||
(lcfg.zfssa_initiator_group == '' or
|
||||
lcfg.zfssa_initiator_group == 'default')):
|
||||
msg = (_('zfssa_initiator: %(ini)s'
|
||||
' wont be used on '
|
||||
'zfssa_initiator_group= %(inigrp)s.')
|
||||
% {'ini': lcfg.zfssa_initiator,
|
||||
'inigrp': lcfg.zfssa_initiator_group})
|
||||
if (lcfg.zfssa_initiator_config != ''):
|
||||
initiator_config = ast.literal_eval(lcfg.zfssa_initiator_config)
|
||||
for initiator_group in initiator_config:
|
||||
zfssa_initiator_group = initiator_group
|
||||
for zfssa_initiator in initiator_config[zfssa_initiator_group]:
|
||||
self.zfssa.create_initiator(zfssa_initiator['iqn'],
|
||||
zfssa_initiator_group + '-' +
|
||||
zfssa_initiator['iqn'],
|
||||
chapuser=
|
||||
zfssa_initiator['user'],
|
||||
chapsecret=
|
||||
zfssa_initiator['password'])
|
||||
if (zfssa_initiator_group != 'default'):
|
||||
self.zfssa.add_to_initiatorgroup(
|
||||
zfssa_initiator['iqn'],
|
||||
zfssa_initiator_group)
|
||||
else:
|
||||
LOG.warning(_LW('zfssa_initiator_config not found. '
|
||||
'Using deprecated configuration options.'))
|
||||
if (lcfg.zfssa_initiator != '' and
|
||||
(lcfg.zfssa_initiator_group == '' or
|
||||
lcfg.zfssa_initiator_group == 'default')):
|
||||
LOG.warning(_LW('zfssa_initiator: %(ini)s'
|
||||
' wont be used on '
|
||||
'zfssa_initiator_group= %(inigrp)s.')
|
||||
% {'ini': lcfg.zfssa_initiator,
|
||||
'inigrp': lcfg.zfssa_initiator_group})
|
||||
|
||||
# Setup initiator and initiator group
|
||||
if (lcfg.zfssa_initiator != '' and
|
||||
lcfg.zfssa_initiator_group != '' and
|
||||
lcfg.zfssa_initiator_group != 'default'):
|
||||
for initiator in lcfg.zfssa_initiator.split(','):
|
||||
self.zfssa.create_initiator(
|
||||
initiator, lcfg.zfssa_initiator_group + '-' +
|
||||
initiator, chapuser=lcfg.zfssa_initiator_user,
|
||||
chapsecret=lcfg.zfssa_initiator_password)
|
||||
self.zfssa.add_to_initiatorgroup(
|
||||
initiator, lcfg.zfssa_initiator_group)
|
||||
|
||||
LOG.warning(msg)
|
||||
# Setup initiator and initiator group
|
||||
if (lcfg.zfssa_initiator != '' and
|
||||
lcfg.zfssa_initiator_group != '' and
|
||||
lcfg.zfssa_initiator_group != 'default'):
|
||||
for initiator in lcfg.zfssa_initiator.split(','):
|
||||
self.zfssa.create_initiator(initiator,
|
||||
lcfg.zfssa_initiator_group + '-' +
|
||||
initiator,
|
||||
chapuser=
|
||||
lcfg.zfssa_initiator_user,
|
||||
chapsecret=
|
||||
lcfg.zfssa_initiator_password)
|
||||
self.zfssa.add_to_initiatorgroup(initiator,
|
||||
lcfg.zfssa_initiator_group)
|
||||
# Parse interfaces
|
||||
interfaces = []
|
||||
for interface in lcfg.zfssa_target_interfaces.split(','):
|
||||
@ -158,11 +177,18 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
||||
self.zfssa.verify_pool(lcfg.zfssa_pool)
|
||||
self.zfssa.verify_project(lcfg.zfssa_pool, lcfg.zfssa_project)
|
||||
|
||||
if (lcfg.zfssa_initiator != '' and
|
||||
lcfg.zfssa_initiator_group != '' and
|
||||
lcfg.zfssa_initiator_group != 'default'):
|
||||
for initiator in lcfg.zfssa_initiator.split(','):
|
||||
self.zfssa.verify_initiator(initiator)
|
||||
if (lcfg.zfssa_initiator_config != ''):
|
||||
initiator_config = ast.literal_eval(lcfg.zfssa_initiator_config)
|
||||
for initiator_group in initiator_config:
|
||||
zfssa_initiator_group = initiator_group
|
||||
for zfssa_initiator in initiator_config[zfssa_initiator_group]:
|
||||
self.zfssa.verify_initiator(zfssa_initiator['iqn'])
|
||||
else:
|
||||
if (lcfg.zfssa_initiator != '' and
|
||||
lcfg.zfssa_initiator_group != '' and
|
||||
lcfg.zfssa_initiator_group != 'default'):
|
||||
for initiator in lcfg.zfssa_initiator.split(','):
|
||||
self.zfssa.verify_initiator(initiator)
|
||||
|
||||
self.zfssa.verify_target(self._get_target_alias())
|
||||
|
||||
@ -197,8 +223,6 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
||||
compression=lcfg.zfssa_lun_compression,
|
||||
logbias=lcfg.zfssa_lun_logbias)
|
||||
|
||||
return self._get_provider_info(volume)
|
||||
|
||||
def delete_volume(self, volume):
|
||||
"""Deletes a volume with the given volume['name']."""
|
||||
LOG.debug('zfssa.delete_volume: name=' + volume['name'])
|
||||
@ -308,35 +332,14 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
||||
self._update_volume_status()
|
||||
return self._stats
|
||||
|
||||
def _export_volume(self, volume):
|
||||
"""Export the volume - set the initiatorgroup property."""
|
||||
LOG.debug('_export_volume: volume name: %s' % volume['name'])
|
||||
lcfg = self.configuration
|
||||
|
||||
self.zfssa.set_lun_initiatorgroup(lcfg.zfssa_pool,
|
||||
lcfg.zfssa_project,
|
||||
volume['name'],
|
||||
lcfg.zfssa_initiator_group)
|
||||
return self._get_provider_info(volume)
|
||||
|
||||
def create_export(self, context, volume):
|
||||
"""Driver entry point to get the export info for a new volume."""
|
||||
LOG.debug('create_export: volume name: %s' % volume['name'])
|
||||
return self._export_volume(volume)
|
||||
pass
|
||||
|
||||
def remove_export(self, context, volume):
|
||||
"""Driver entry point to remove an export for a volume."""
|
||||
LOG.debug('remove_export: volume name: %s' % volume['name'])
|
||||
lcfg = self.configuration
|
||||
self.zfssa.set_lun_initiatorgroup(lcfg.zfssa_pool,
|
||||
lcfg.zfssa_project,
|
||||
volume['name'],
|
||||
'')
|
||||
pass
|
||||
|
||||
def ensure_export(self, context, volume):
|
||||
"""Driver entry point to get the export info for an existing volume."""
|
||||
LOG.debug('ensure_export: volume name: %s' % volume['name'])
|
||||
return self._export_volume(volume)
|
||||
pass
|
||||
|
||||
def copy_image_to_volume(self, context, volume, image_service, image_id):
|
||||
self.ensure_export(context, volume)
|
||||
@ -387,3 +390,42 @@ class ZFSSAISCSIDriver(driver.ISCSIDriver):
|
||||
lcfg.zfssa_project,
|
||||
snapshot['volume_name'])
|
||||
return lun['size'] == size
|
||||
|
||||
def initialize_connection(self, volume, connector):
|
||||
lcfg = self.configuration
|
||||
init_groups = self.zfssa.get_initiator_initiatorgroup(
|
||||
connector['initiator'])
|
||||
for initiator_group in init_groups:
|
||||
self.zfssa.set_lun_initiatorgroup(lcfg.zfssa_pool,
|
||||
lcfg.zfssa_project,
|
||||
volume['name'],
|
||||
initiator_group)
|
||||
iscsi_properties = {}
|
||||
provider = self._get_provider_info(volume)
|
||||
(target_portal, iqn, lun) = provider['provider_location'].split()
|
||||
iscsi_properties['target_discovered'] = False
|
||||
iscsi_properties['target_portal'] = target_portal
|
||||
iscsi_properties['target_iqn'] = iqn
|
||||
iscsi_properties['target_lun'] = lun
|
||||
iscsi_properties['volume_id'] = volume['id']
|
||||
|
||||
if 'provider_auth' in provider:
|
||||
(auth_method, auth_username, auth_password) = provider[
|
||||
'provider_auth'].split()
|
||||
iscsi_properties['auth_method'] = auth_method
|
||||
iscsi_properties['auth_username'] = auth_username
|
||||
iscsi_properties['auth_password'] = auth_password
|
||||
|
||||
return {
|
||||
'driver_volume_type': 'iscsi',
|
||||
'data': iscsi_properties
|
||||
}
|
||||
|
||||
def terminate_connection(self, volume, connector, **kwargs):
|
||||
"""Driver entry point to terminate a connection for a volume."""
|
||||
LOG.debug('terminate_connection: volume name: %s.' % volume['name'])
|
||||
lcfg = self.configuration
|
||||
self.zfssa.set_lun_initiatorgroup(lcfg.zfssa_pool,
|
||||
lcfg.zfssa_project,
|
||||
volume['name'],
|
||||
'')
|
||||
|
@ -17,7 +17,7 @@ ZFS Storage Appliance Proxy
|
||||
import json
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
from cinder.i18n import _, _LE
|
||||
from cinder.openstack.common import log
|
||||
from cinder.volume.drivers.zfssa import restclient
|
||||
|
||||
@ -628,3 +628,22 @@ class ZFSSAApi(object):
|
||||
|
||||
val = json.loads(ret.data)
|
||||
return val['snapshot']['numclones'] != 0
|
||||
|
||||
def get_initiator_initiatorgroup(self, initiator):
|
||||
"""Returns the initiator group of the initiator."""
|
||||
groups = []
|
||||
svc = "/api/san/v1/iscsi/initiator-groups"
|
||||
ret = self.rclient.get(svc)
|
||||
if ret.status != restclient.Status.OK:
|
||||
LOG.error(_LE('Error getting initiator groups.'))
|
||||
exception_msg = (_('Error getting initiator groups.'))
|
||||
raise exception.VolumeBackendAPIException(data=exception_msg)
|
||||
val = json.loads(ret.data)
|
||||
for initiator_group in val['groups']:
|
||||
if initiator in initiator_group['initiators']:
|
||||
groups.append(initiator_group["name"])
|
||||
if len(groups) == 0:
|
||||
LOG.debug("Initiator group not found. Attaching volume to "
|
||||
"default initiator group.")
|
||||
groups.append('default')
|
||||
return groups
|
||||
|
@ -2315,6 +2315,9 @@
|
||||
# iSCSI initiator CHAP password. (string value)
|
||||
#zfssa_initiator_password=
|
||||
|
||||
# iSCSI initiators configuration. (string value)
|
||||
#zfssa_initiator_config=
|
||||
|
||||
# iSCSI target group name. (string value)
|
||||
#zfssa_target_group=tgt-grp
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user