gluster*: add proper getter/setters for volume options

GlusterManager:
- add various error policies to gluster_call
- add set_vol_option method, with optional error tolerance
  (making use of the respective gluster call error policy),
  with support for Boolean options
- rename get_gluster_vol_option method to get_vol_option
  for uniform nomenclature and simplicity (the "gluster" in
  the method name was redundant as the classname already
  hints about the Gluster scope)

  Partially implements bp gluster-code-cleanup

Change-Id: I02a1d591d36c6a64eea55ed64cf715f94c1fd1c8
This commit is contained in:
Csaba Henk 2016-01-22 14:48:41 +01:00
parent ba159a9ea3
commit 5847a12260
10 changed files with 260 additions and 269 deletions

View File

@ -33,7 +33,6 @@ from oslo_log import log
from manila import exception
from manila.i18n import _
from manila.i18n import _LE
from manila.share import driver
from manila.share.drivers import ganesha
from manila.share.drivers.ganesha import utils as ganesha_utils
@ -98,7 +97,7 @@ class GlusterfsShareDriver(driver.ExecuteMixin, driver.GaneshaMixin,
# TODO(csaba): This should be refactored into proper dispatch to helper
if self.nfs_helper == GlusterNFSHelper and not gluster_manager.path:
# default is 'on'
export_vol = gluster_manager.get_gluster_vol_option(
export_vol = gluster_manager.get_vol_option(
NFS_EXPORT_VOL) or 'on'
if export_vol.lower() not in ('on', '1', 'true', 'yes', 'enable'):
raise exception.GlusterfsException(
@ -108,12 +107,8 @@ class GlusterfsShareDriver(driver.ExecuteMixin, driver.GaneshaMixin,
else:
# gluster-nfs export of the whole volume must be prohibited
# to not to defeat access control
setting = [NFS_EXPORT_VOL, 'off']
args = ['volume', 'set', gluster_manager.volume] + setting
gluster_manager.gluster_call(
*args,
log=_LE("Tuning the GlusterFS volume to prevent exporting the "
"entire volume"))
setting = [NFS_EXPORT_VOL, False]
gluster_manager.set_vol_option(*setting)
return self.nfs_helper(self._execute, self.configuration,
gluster_manager=gluster_manager).get_export(
share_manager['share'])
@ -169,7 +164,7 @@ class GlusterNFSHelper(ganesha.NASHelperBase):
def _get_export_dir_dict(self):
"""Get the export entries of shares in the GlusterFS volume."""
export_dir = self.gluster_manager.get_gluster_vol_option(
export_dir = self.gluster_manager.get_vol_option(
NFS_EXPORT_DIR)
edh = {}
if export_dir:
@ -219,14 +214,9 @@ class GlusterNFSHelper(ganesha.NASHelperBase):
if export_dir_dict:
export_dir_new = (",".join("/%s(%s)" % (d, "|".join(v))
for d, v in sorted(export_dir_dict.items())))
args = ('volume', 'set', self.gluster_manager.volume,
NFS_EXPORT_DIR, export_dir_new)
else:
args = ('volume', 'reset', self.gluster_manager.volume,
NFS_EXPORT_DIR)
self.gluster_manager.gluster_call(
*args,
log=_LE("Tuning GlusterFS volume options"))
export_dir_new = None
self.gluster_manager.set_vol_option(NFS_EXPORT_DIR, export_dir_new)
def allow_access(self, base, share, access):
"""Allow access to a share."""
@ -262,7 +252,7 @@ class GlusterNFSVolHelper(GlusterNFSHelper):
**kwargs)
def _get_vol_exports(self):
export_vol = self.gluster_manager.get_gluster_vol_option(
export_vol = self.gluster_manager.get_vol_option(
NFS_RPC_AUTH_ALLOW)
return export_vol.split(',') if export_vol else []
@ -293,19 +283,13 @@ class GlusterNFSVolHelper(GlusterNFSHelper):
return
if export_vol_list:
argseq = (('volume', 'set', self.gluster_manager.volume,
NFS_RPC_AUTH_ALLOW, ','.join(export_vol_list)),
('volume', 'reset', self.gluster_manager.volume,
NFS_RPC_AUTH_REJECT))
argseq = ((NFS_RPC_AUTH_ALLOW, ','.join(export_vol_list)),
(NFS_RPC_AUTH_REJECT, None))
else:
argseq = (('volume', 'reset', self.gluster_manager.volume,
NFS_RPC_AUTH_ALLOW),
('volume', 'set', self.gluster_manager.volume,
NFS_RPC_AUTH_REJECT, '*'))
argseq = ((NFS_RPC_AUTH_ALLOW, None),
(NFS_RPC_AUTH_REJECT, '*'))
for args in argseq:
self.gluster_manager.gluster_call(
*args,
log=_LE("Tuning GlusterFS volume options"))
self.gluster_manager.set_vol_option(*args)
def allow_access(self, base, share, access):
"""Allow access to a share."""

View File

@ -50,6 +50,17 @@ CONF = cfg.CONF
CONF.register_opts(glusterfs_common_opts)
def _check_volume_presence(f):
def wrapper(self, *args, **kwargs):
if not self.components.get('volume'):
raise exception.GlusterfsException(
_("Gluster address does not have a volume component."))
return f(self, *args, **kwargs)
return wrapper
class GlusterManager(object):
"""Interface with a GlusterFS volume."""
@ -136,12 +147,22 @@ class GlusterManager(object):
def _gluster_call(*args, **kwargs):
logmsg = kwargs.pop('log', None)
raw_error = kwargs.pop('raw_error', False)
error_policy = kwargs.pop('error_policy', 'coerce')
if (error_policy not in ('raw', 'coerce', 'suppress') and
not isinstance(error_policy[0], int)):
raise TypeError(_("undefined error_policy %s") %
repr(error_policy))
try:
return gluster_execf(*(('gluster',) + args), **kwargs)
except exception.ProcessExecutionError as exc:
if raw_error:
if error_policy == 'raw':
raise
elif error_policy == 'coerce':
pass
elif (error_policy == 'suppress' or
exc.exit_code in error_policy):
return
if logmsg:
LOG.error(_LE("%s: GlusterFS instrumentation failed.") %
logmsg)
@ -153,7 +174,8 @@ class GlusterManager(object):
return _gluster_call
def get_gluster_vol_option(self, option):
@_check_volume_presence
def get_vol_option(self, option):
"""Get the value of an option set on a GlusterFS volume."""
args = ('--xml', 'volume', 'info', self.volume)
out, err = self.gluster_call(*args, log=_LE("retrieving volume info"))
@ -172,6 +194,18 @@ class GlusterManager(object):
if o == option:
return v
@_check_volume_presence
def set_vol_option(self, option, value, ignore_failure=False):
if value is True:
value
value = {True: 'on', False: 'off'}.get(value, value)
if value is None:
args = ('reset', (option,))
else:
args = ('set', (option, value))
self.gluster_call(
'volume', args[0], self.volume, *args[1], error_policy=(1,))
def get_gluster_version(self):
"""Retrieve GlusterFS version.

View File

@ -82,7 +82,7 @@ class GlusterfsDirectoryMappedLayout(layout.GlusterfsShareLayoutBase):
self.gluster_manager.gluster_call(*args)
except exception.GlusterfsException:
if (self.gluster_manager.
get_gluster_vol_option('features.quota')) != 'on':
get_vol_option('features.quota')) != 'on':
LOG.error(_LE("Error in tuning GlusterFS volume to enable "
"creation of shares of specific size."))
raise

View File

@ -218,7 +218,7 @@ class GlusterfsVolumeMappedLayout(layout.GlusterfsShareLayoutBase):
comp_vol.update({'volume': volname})
gluster_mgr_vol = self._glustermanager(comp_vol)
if filter_used:
vshr = gluster_mgr_vol.get_gluster_vol_option(
vshr = gluster_mgr_vol.get_vol_option(
USER_MANILA_SHARE) or ''
if UUID_RE.search(vshr):
continue
@ -398,8 +398,7 @@ class GlusterfsVolumeMappedLayout(layout.GlusterfsShareLayoutBase):
{'share': share, 'manager': gmgr})
self.private_storage.update(share['id'], {'volume': vol})
args = ('volume', 'set', gmgr.volume, USER_MANILA_SHARE, share['id'])
gmgr.gluster_call(*args)
gmgr.set_vol_option(USER_MANILA_SHARE, share['id'])
# TODO(deepakcs): Enable quota and set it to the share size.
@ -416,20 +415,18 @@ class GlusterfsVolumeMappedLayout(layout.GlusterfsShareLayoutBase):
volume back in the available list.
"""
gmgr = self._share_manager(share)
clone_of = gmgr.get_gluster_vol_option(USER_CLONED_FROM) or ''
clone_of = gmgr.get_vol_option(USER_CLONED_FROM) or ''
try:
if UUID_RE.search(clone_of):
# We take responsibility for the lifecycle
# management of those volumes which were
# created by us (as snapshot clones) ...
args = ('volume', 'delete', gmgr.volume)
gmgr.gluster_call('volume', 'delete', gmgr.volume)
else:
# ... for volumes that come from the pool, we return
# them to the pool (after some purification rituals)
self._wipe_gluster_vol(gmgr)
args = ('volume', 'set', gmgr.volume, USER_MANILA_SHARE,
'NONE')
gmgr.gluster_call(*args)
gmgr.set_vol_option(USER_MANILA_SHARE, 'NONE')
self._push_gluster_vol(gmgr.qualified)
except exception.GlusterfsException:
@ -594,8 +591,7 @@ class GlusterfsVolumeMappedLayout(layout.GlusterfsShareLayoutBase):
gmgr = self._share_manager(share)
self.gluster_used_vols.add(gmgr.qualified)
args = ('volume', 'set', gmgr.volume, USER_MANILA_SHARE, share['id'])
gmgr.gluster_call(*args)
gmgr.set_vol_option(USER_MANILA_SHARE, share['id'])
# Debt...

View File

@ -31,7 +31,6 @@ from oslo_log import log
from manila import exception
from manila.i18n import _
from manila.i18n import _LE
from manila.i18n import _LW
from manila.share import driver
from manila.share.drivers.glusterfs import common
@ -81,7 +80,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
gluster_mgr_parent = (share_mgr_parent or {}).get('manager', None)
ssl_allow_opt = (gluster_mgr_parent if gluster_mgr_parent else
gluster_mgr).get_gluster_vol_option(
gluster_mgr).get_vol_option(
AUTH_SSL_ALLOW)
if not ssl_allow_opt:
# Not having AUTH_SSL_ALLOW set is a problematic edge case.
@ -124,33 +123,14 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
gluster_actions.append((AUTH_SSL_ALLOW, access_to))
for option, value in (
(NFS_EXPORT_VOL, 'off'), (CLIENT_SSL, 'on'), (SERVER_SSL, 'on')
(NFS_EXPORT_VOL, False), (CLIENT_SSL, True), (SERVER_SSL, True)
):
gluster_actions.append((option, value))
for action in gluster_actions:
gluster_mgr.gluster_call(
'volume', 'set', gluster_mgr.volume, *action,
log=_LE('Setting up GlusterFS volume'))
gluster_mgr.set_vol_option(*action)
try:
gluster_mgr.gluster_call(
'volume', 'set', gluster_mgr.volume, DYNAMIC_AUTH, 'on',
raw_error=True)
except exception.ProcessExecutionError as exc:
if exc.exit_code == 1:
# 'dynamic-auth' is not supported by gluster backend,
# that's OK
pass
else:
msg = (_("Error in gluster volume set during volume "
"setup. volume: %(volname)s, option: %(option)s, "
"value: %(value)s, error: %(error)s") %
{'volname': gluster_mgr.volume,
'option': option, 'value': value,
'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)
gluster_mgr.set_vol_option(DYNAMIC_AUTH, True, ignore_failure=True)
# SSL enablement requires a fresh volume start
# to take effect
@ -176,7 +156,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
raise exception.InvalidShareAccess(_("Only 'cert' access type "
"allowed"))
ssl_allow_opt = gluster_mgr.get_gluster_vol_option(AUTH_SSL_ALLOW)
ssl_allow_opt = gluster_mgr.get_vol_option(AUTH_SSL_ALLOW)
# wrt. GlusterFS' parsing of auth.ssl-allow, please see code from
# https://github.com/gluster/glusterfs/blob/v3.6.2/
# xlators/protocol/auth/login/src/login.c#L80
@ -193,10 +173,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
ssl_allow.append(access_to)
ssl_allow_opt = ','.join(ssl_allow)
gluster_mgr.gluster_call(
'volume', 'set', gluster_mgr.volume,
AUTH_SSL_ALLOW, ssl_allow_opt,
log=_LE("Tuning GlusterFS volume in allow-access"))
gluster_mgr.set_vol_option(AUTH_SSL_ALLOW, ssl_allow_opt)
@utils.synchronized("glusterfs_native_access", external=False)
def _deny_access_via_manager(self, gluster_mgr, context, share, access,
@ -211,7 +188,7 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
"allowed for access "
"removal."))
ssl_allow_opt = gluster_mgr.get_gluster_vol_option(AUTH_SSL_ALLOW)
ssl_allow_opt = gluster_mgr.get_vol_option(AUTH_SSL_ALLOW)
ssl_allow = re.split('[ ,]', ssl_allow_opt)
access_to = access['access_to']
if access_to not in ssl_allow:
@ -224,12 +201,9 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
ssl_allow.remove(access_to)
ssl_allow_opt = ','.join(ssl_allow)
gluster_mgr.gluster_call(
'volume', 'set', gluster_mgr.volume,
AUTH_SSL_ALLOW, ssl_allow_opt,
log=_LE("Tuning GlusterFS volume in deny-access"))
gluster_mgr.set_vol_option(AUTH_SSL_ALLOW, ssl_allow_opt)
dynauth = gluster_mgr.get_gluster_vol_option(DYNAMIC_AUTH) or 'off'
dynauth = gluster_mgr.get_vol_option(DYNAMIC_AUTH) or 'off'
# TODO(csaba): boolean option processing shoud be done in common
if dynauth.lower() not in ('on', '1', 'true', 'yes', 'enable'):
common._restart_gluster_vol(gluster_mgr)

View File

@ -63,6 +63,16 @@ class GlusterManagerTestCase(test.TestCase):
'testuser@127.0.0.1:/testvol', self.fake_execf,
fake_path_to_private_key, fake_remote_server_password)
def test_check_volume_presence(self):
common._check_volume_presence(mock.Mock())(self._gluster_manager)
def test_check_volume_presence_error(self):
gmgr = common.GlusterManager('testuser@127.0.0.1')
self.assertRaises(
exception.GlusterfsException,
common._check_volume_presence(mock.Mock()), gmgr)
def test_gluster_manager_init(self):
self.assertEqual(fake_gluster_manager_attrs['user'],
self._gluster_manager.user)
@ -128,15 +138,23 @@ class GlusterManagerTestCase(test.TestCase):
self.assertRaises(AttributeError, getattr, self._gluster_manager,
'fakeprop')
def test_gluster_manager_make_gluster_call_local(self):
fake_obj = mock.Mock()
@ddt.data({'mockargs': {}, 'kwargs': {}},
{'mockargs': {'side_effect': exception.ProcessExecutionError},
'kwargs': {'error_policy': 'suppress'}},
{'mockargs': {
'side_effect': exception.ProcessExecutionError(exit_code=2)},
'kwargs': {'error_policy': (2,)}})
@ddt.unpack
def test_gluster_manager_make_gluster_call_local(self, mockargs, kwargs):
fake_obj = mock.Mock(**mockargs)
fake_execute = mock.Mock()
kwargs.update(fake_kwargs)
with mock.patch.object(common.ganesha_utils, 'RootExecutor',
mock.Mock(return_value=fake_obj)):
gluster_manager = common.GlusterManager(
'127.0.0.1:/testvol', self.fake_execf)
gluster_manager.make_gluster_call(fake_execute)(*fake_args,
**fake_kwargs)
**kwargs)
common.ganesha_utils.RootExecutor.assert_called_with(
fake_execute)
fake_obj.assert_called_once_with(
@ -161,12 +179,15 @@ class GlusterManagerTestCase(test.TestCase):
@ddt.data({'trouble': exception.ProcessExecutionError,
'_exception': exception.GlusterfsException, 'xkw': {}},
{'trouble': exception.ProcessExecutionError(exit_code=2),
'_exception': exception.GlusterfsException,
'xkw': {'error_policy': (1,)}},
{'trouble': exception.ProcessExecutionError,
'_exception': exception.GlusterfsException,
'xkw': {'raw_error': False}},
'xkw': {'error_policy': 'coerce'}},
{'trouble': exception.ProcessExecutionError,
'_exception': exception.ProcessExecutionError,
'xkw': {'raw_error': True}},
'xkw': {'error_policy': 'raw'}},
{'trouble': RuntimeError, '_exception': RuntimeError, 'xkw': {}})
@ddt.unpack
def test_gluster_manager_make_gluster_call_error(self, trouble,
@ -189,17 +210,29 @@ class GlusterManagerTestCase(test.TestCase):
fake_obj.assert_called_once_with(
*(('gluster',) + fake_args), **fake_kwargs)
def test_get_gluster_vol_option_empty_volinfo(self):
def test_gluster_manager_make_gluster_call_bad_policy(self):
fake_obj = mock.Mock()
fake_execute = mock.Mock()
with mock.patch.object(common.ganesha_utils, 'RootExecutor',
mock.Mock(return_value=fake_obj)):
gluster_manager = common.GlusterManager(
'127.0.0.1:/testvol', self.fake_execf)
self.assertRaises(TypeError,
gluster_manager.make_gluster_call(fake_execute),
*fake_args, error_policy='foobar')
def test_get_vol_option_empty_volinfo(self):
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(return_value=('', {})))
self.assertRaises(exception.GlusterfsException,
self._gluster_manager.get_gluster_vol_option,
self._gluster_manager.get_vol_option,
NFS_EXPORT_DIR)
self._gluster_manager.gluster_call.assert_called_once_with(
*args, log=mock.ANY)
def test_get_gluster_vol_option_ambiguous_volinfo(self):
def test_get_vol_option_ambiguous_volinfo(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@ -215,12 +248,12 @@ class GlusterManagerTestCase(test.TestCase):
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
self.assertRaises(exception.InvalidShare,
self._gluster_manager.get_gluster_vol_option,
self._gluster_manager.get_vol_option,
NFS_EXPORT_DIR)
self._gluster_manager.gluster_call.assert_called_once_with(
*args, log=mock.ANY)
def test_get_gluster_vol_option_trivial_volinfo(self):
def test_get_vol_option_trivial_volinfo(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@ -237,12 +270,12 @@ class GlusterManagerTestCase(test.TestCase):
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
ret = self._gluster_manager.get_vol_option(NFS_EXPORT_DIR)
self.assertIsNone(ret)
self._gluster_manager.gluster_call.assert_called_once_with(
*args, log=mock.ANY)
def test_get_gluster_vol_option(self):
def test_get_vol_option(self):
def xml_output(*ignore_args, **ignore_kwargs):
return """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@ -265,11 +298,25 @@ class GlusterManagerTestCase(test.TestCase):
args = ('--xml', 'volume', 'info', self._gluster_manager.volume)
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(side_effect=xml_output))
ret = self._gluster_manager.get_gluster_vol_option(NFS_EXPORT_DIR)
ret = self._gluster_manager.get_vol_option(NFS_EXPORT_DIR)
self.assertEqual('/foo(10.0.0.1|10.0.0.2),/bar(10.0.0.1)', ret)
self._gluster_manager.gluster_call.assert_called_once_with(
*args, log=mock.ANY)
@ddt.data({'setting': 'some_value', 'args': ('set', 'some_value')},
{'setting': None, 'args': ('reset',)},
{'setting': True, 'args': ('set', 'on')},
{'setting': False, 'args': ('set', 'off')})
@ddt.unpack
def test_set_vol_option(self, setting, args):
self.mock_object(self._gluster_manager, 'gluster_call', mock.Mock())
self._gluster_manager.set_vol_option('an_option', setting)
self._gluster_manager.gluster_call.assert_called_once_with(
'volume', args[0], 'testvol', 'an_option', *args[1:],
error_policy=(1,))
def test_get_gluster_version(self):
self.mock_object(self._gluster_manager, 'gluster_call',
mock.Mock(return_value=('glusterfs 3.6.2beta3', '')))

View File

@ -111,7 +111,7 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
def test_do_setup_error_enabling_creation_share_specific_size(self):
attrs = {'volume': 'testvol',
'gluster_call.side_effect': exception.GlusterfsException,
'get_gluster_vol_option.return_value': 'off'}
'get_vol_option.return_value': 'off'}
fake_gluster_manager = mock.Mock(**attrs)
self.mock_object(layout_directory.LOG, 'error')
methods = ('_check_mount_glusterfs', '_ensure_gluster_vol_mounted')
@ -131,7 +131,7 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
requires={'volume': True})
self._layout.gluster_manager.gluster_call.assert_called_once_with(
'volume', 'quota', 'testvol', 'enable')
(self._layout.gluster_manager.get_gluster_vol_option.
(self._layout.gluster_manager.get_vol_option.
assert_called_once_with('features.quota'))
layout_directory.LOG.error.assert_called_once_with(mock.ANY)
self._layout._check_mount_glusterfs.assert_called_once_with()
@ -140,7 +140,7 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
def test_do_setup_error_already_enabled_creation_share_specific_size(self):
attrs = {'volume': 'testvol',
'gluster_call.side_effect': exception.GlusterfsException,
'get_gluster_vol_option.return_value': 'on'}
'get_vol_option.return_value': 'on'}
fake_gluster_manager = mock.Mock(**attrs)
self.mock_object(layout_directory.LOG, 'error')
methods = ('_check_mount_glusterfs', '_ensure_gluster_vol_mounted')
@ -159,7 +159,7 @@ class GlusterfsDirectoryMappedLayoutTestCase(test.TestCase):
requires={'volume': True})
self._layout.gluster_manager.gluster_call.assert_called_once_with(
'volume', 'quota', 'testvol', 'enable')
(self._layout.gluster_manager.get_gluster_vol_option.
(self._layout.gluster_manager.get_vol_option.
assert_called_once_with('features.quota'))
self.assertFalse(layout_directory.LOG.error.called)
self._layout._check_mount_glusterfs.assert_called_once_with()

View File

@ -168,11 +168,11 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
def test_fetch_gluster_volumes(self, sharemark):
vol1_qualified = 'root@host1:/manila-share-1-1G'
gmgr_vol1 = common.GlusterManager(vol1_qualified)
gmgr_vol1.get_gluster_vol_option = mock.Mock(
gmgr_vol1.get_vol_option = mock.Mock(
return_value=sharemark[vol1_qualified])
vol2_qualified = 'root@host2:/manila-share-2-2G'
gmgr_vol2 = common.GlusterManager(vol2_qualified)
gmgr_vol2.get_gluster_vol_option = mock.Mock(
gmgr_vol2.get_vol_option = mock.Mock(
return_value=sharemark[vol2_qualified])
self.mock_object(
self.gmgr1, 'gluster_call',
@ -195,19 +195,19 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
log=mock.ANY)
self.gmgr2.gluster_call.assert_called_once_with(*test_args,
log=mock.ANY)
gmgr_vol1.get_gluster_vol_option.assert_called_once_with(
gmgr_vol1.get_vol_option.assert_called_once_with(
'user.manila-share')
gmgr_vol2.get_gluster_vol_option.assert_called_once_with(
gmgr_vol2.get_vol_option.assert_called_once_with(
'user.manila-share')
self.assertEqual(expected_output, ret)
def test_fetch_gluster_volumes_no_filter_used(self):
vol1_qualified = 'root@host1:/manila-share-1-1G'
gmgr_vol1 = common.GlusterManager(vol1_qualified)
gmgr_vol1.get_gluster_vol_option = mock.Mock()
gmgr_vol1.get_vol_option = mock.Mock()
vol2_qualified = 'root@host2:/manila-share-2-2G'
gmgr_vol2 = common.GlusterManager(vol2_qualified)
gmgr_vol2.get_gluster_vol_option = mock.Mock()
gmgr_vol2.get_vol_option = mock.Mock()
self.mock_object(
self.gmgr1, 'gluster_call',
mock.Mock(return_value=(self.glusterfs_server1_volumes, '')))
@ -226,14 +226,14 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
log=mock.ANY)
self.gmgr2.gluster_call.assert_called_once_with(*test_args,
log=mock.ANY)
self.assertFalse(gmgr_vol1.get_gluster_vol_option.called)
self.assertFalse(gmgr_vol2.get_gluster_vol_option.called)
self.assertFalse(gmgr_vol1.get_vol_option.called)
self.assertFalse(gmgr_vol2.get_vol_option.called)
self.assertEqual(expected_output, ret)
def test_fetch_gluster_volumes_no_keymatch(self):
vol1_qualified = 'root@host1:/manila-share-1'
gmgr_vol1 = common.GlusterManager(vol1_qualified)
gmgr_vol1.get_gluster_vol_option = mock.Mock(return_value=None)
gmgr_vol1.get_vol_option = mock.Mock(return_value=None)
self._layout.configuration.glusterfs_servers = [self.glusterfs_server1]
self.mock_object(
self.gmgr1, 'gluster_call',
@ -350,7 +350,7 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
share = self.share1
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
gmgr1.gluster_call = mock.Mock()
gmgr1.set_vol_option = mock.Mock()
self.mock_object(self._layout, '_share_manager',
mock.Mock(return_value=gmgr1))
@ -358,8 +358,8 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
self._layout._share_manager.assert_called_once_with(share)
self.assertIn(self.glusterfs_target1, self._layout.gluster_used_vols)
gmgr1.gluster_call.assert_called_once_with(
'volume', 'set', 'gv1', 'user.manila-share', share['id'])
gmgr1.set_vol_option.assert_called_once_with(
'user.manila-share', share['id'])
@ddt.data({"voldict": {"host:/share2G": {"size": 2}}, "used_vols": set(),
"size": 1, "expected": "host:/share2G"},
@ -540,7 +540,7 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
self._layout._pop_gluster_vol = mock.Mock(
return_value=self.glusterfs_target1)
gmgr1 = common.GlusterManager(self.glusterfs_target1)
gmgr1.gluster_call = mock.Mock()
gmgr1.set_vol_option = mock.Mock()
self.mock_object(self._layout, '_glustermanager',
mock.Mock(return_value=gmgr1))
self.mock_object(self.fake_driver, '_setup_via_manager',
@ -554,8 +554,8 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
{'manager': gmgr1, 'share': share})
self._layout.private_storage.update.assert_called_once_with(
share['id'], {'volume': self.glusterfs_target1})
gmgr1.gluster_call.assert_called_once_with(
'volume', 'set', 'gv1', 'user.manila-share', share['id'])
gmgr1.set_vol_option.assert_called_once_with(
'user.manila-share', share['id'])
self.assertEqual('host1:/gv1', exp_locn)
def test_create_share_error(self):
@ -575,23 +575,23 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
self._layout._wipe_gluster_vol = mock.Mock()
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
gmgr1.gluster_call = mock.Mock()
gmgr1.get_gluster_vol_option = mock.Mock(return_value=clone_of)
gmgr1.set_vol_option = mock.Mock()
gmgr1.get_vol_option = mock.Mock(return_value=clone_of)
self.mock_object(self._layout, '_glustermanager',
mock.Mock(return_value=gmgr1))
self._layout.gluster_used_vols = set([self.glusterfs_target1])
self._layout.delete_share(self._context, self.share1)
gmgr1.get_gluster_vol_option.assert_called_once_with(
gmgr1.get_vol_option.assert_called_once_with(
'user.manila-cloned-from')
self._layout._wipe_gluster_vol.assert_called_once_with(gmgr1)
self._layout._push_gluster_vol.assert_called_once_with(
self.glusterfs_target1)
self._layout.private_storage.delete.assert_called_once_with(
self.share1['id'])
gmgr1.gluster_call.assert_called_once_with(
'volume', 'set', 'gv1', 'user.manila-share', 'NONE')
gmgr1.set_vol_option.assert_called_once_with(
'user.manila-share', 'NONE')
def test_delete_share_clone(self):
self._layout._push_gluster_vol = mock.Mock()
@ -599,14 +599,14 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
gmgr1.gluster_call = mock.Mock()
gmgr1.get_gluster_vol_option = mock.Mock(return_value=FAKE_UUID1)
gmgr1.get_vol_option = mock.Mock(return_value=FAKE_UUID1)
self.mock_object(self._layout, '_glustermanager',
mock.Mock(return_value=gmgr1))
self._layout.gluster_used_vols = set([self.glusterfs_target1])
self._layout.delete_share(self._context, self.share1)
gmgr1.get_gluster_vol_option.assert_called_once_with(
gmgr1.get_vol_option.assert_called_once_with(
'user.manila-cloned-from')
self.assertFalse(self._layout._wipe_gluster_vol.called)
self._layout._push_gluster_vol.assert_called_once_with(
@ -623,7 +623,7 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
self._layout._push_gluster_vol = mock.Mock()
gmgr = common.GlusterManager
gmgr1 = gmgr(self.glusterfs_target1, self._execute, None, None)
gmgr1.get_gluster_vol_option = mock.Mock(return_value=None)
gmgr1.get_vol_option = mock.Mock(return_value=None)
self.mock_object(self._layout, '_glustermanager',
mock.Mock(return_value=gmgr1))
self._layout.gluster_used_vols = set([self.glusterfs_target1])
@ -799,9 +799,9 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
mock.Mock(side_effect=[('', ''), ('', '')]))
self.mock_object(new_gmgr, 'gluster_call',
mock.Mock(side_effect=[('', ''), ('', ''), ('', '')]))
self.mock_object(new_gmgr, 'get_gluster_vol_option',
self.mock_object(new_gmgr, 'get_vol_option',
mock.Mock())
new_gmgr.get_gluster_vol_option.return_value = (
new_gmgr.get_vol_option.return_value = (
'glusterfs-server-1,client')
self.mock_object(self._layout, '_find_actual_backend_snapshot_name',
mock.Mock(return_value='fake_snap_id_xyz'))
@ -857,9 +857,9 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
self.mock_object(
old_gmgr, 'gluster_call',
mock.Mock(side_effect=[('', ''), ('', '')]))
self.mock_object(new_gmgr, 'get_gluster_vol_option',
self.mock_object(new_gmgr, 'get_vol_option',
mock.Mock())
new_gmgr.get_gluster_vol_option.return_value = (
new_gmgr.get_vol_option.return_value = (
'glusterfs-server-1,client')
self.mock_object(self._layout, '_find_actual_backend_snapshot_name',
mock.Mock(return_value='fake_snap_id_xyz'))
@ -882,7 +882,7 @@ class GlusterfsVolumeMappedLayoutTestCase(test.TestCase):
self._layout._share_manager.assert_called_once_with(
snapshot['share_instance'])
self.assertFalse(self._layout._glustermanager.called)
self.assertFalse(new_gmgr.get_gluster_vol_option.called)
self.assertFalse(new_gmgr.get_vol_option.called)
self.assertFalse(new_gmgr.gluster_call.called)
self.assertNotIn(new_vol_addr,
self._layout.glusterfs_versions.keys())

View File

@ -86,7 +86,6 @@ class GlusterfsShareDriverTestCase(test.TestCase):
@ddt.data(True, False)
def test_setup_via_manager(self, has_parent):
gmgr = mock.Mock()
gmgr.gluster_call = mock.Mock()
share_mgr_parent = mock.Mock() if has_parent else None
nfs_helper = mock.Mock()
nfs_helper.get_export = mock.Mock(return_value='host:/vol')
@ -96,9 +95,8 @@ class GlusterfsShareDriverTestCase(test.TestCase):
{'manager': gmgr, 'share': self.share},
share_manager_parent=share_mgr_parent)
gmgr.gluster_call.assert_called_once_with(
'volume', 'set', gmgr.volume, 'nfs.export-volumes', 'off',
log=mock.ANY)
gmgr.set_vol_option.assert_called_once_with(
'nfs.export-volumes', False)
self._driver.nfs_helper.assert_called_once_with(
self._execute, self.fake_conf, gluster_manager=gmgr)
nfs_helper.get_export.assert_called_once_with(self.share)
@ -111,7 +109,6 @@ class GlusterfsShareDriverTestCase(test.TestCase):
@ddt.unpack
def test_setup_via_manager_path(self, helpercls, path):
gmgr = mock.Mock()
gmgr.gluster_call = mock.Mock()
gmgr.path = path
if not helpercls:
helper = mock.Mock()
@ -119,32 +116,31 @@ class GlusterfsShareDriverTestCase(test.TestCase):
helpercls = mock.Mock(return_value=helper)
self._driver.nfs_helper = helpercls
if helpercls == glusterfs.GlusterNFSHelper and path is None:
gmgr.get_gluster_vol_option = mock.Mock(return_value='on')
gmgr.get_vol_option = mock.Mock(return_value='on')
self._driver._setup_via_manager(
{'manager': gmgr, 'share': self.share})
if helpercls == glusterfs.GlusterNFSHelper and path is None:
gmgr.get_gluster_vol_option.assert_called_once_with(
gmgr.get_vol_option.assert_called_once_with(
NFS_EXPORT_VOL)
args = (NFS_RPC_AUTH_REJECT, '*')
else:
args = (NFS_EXPORT_VOL, 'off')
gmgr.gluster_call.assert_called_once_with(
'volume', 'set', gmgr.volume, *args, log=mock.ANY)
args = (NFS_EXPORT_VOL, False)
gmgr.set_vol_option.assert_called_once_with(*args)
@ddt.data('off', 'no', '0', 'false', 'disable', 'foobarbaz')
def test_setup_via_manager_export_volumes_on(self, export_vol):
gmgr = mock.Mock()
gmgr.path = None
gmgr.get_gluster_vol_option = mock.Mock(return_value=export_vol)
gmgr.get_vol_option = mock.Mock(return_value=export_vol)
self._driver.nfs_helper = glusterfs.GlusterNFSHelper
self.assertRaises(exception.GlusterfsException,
self._driver._setup_via_manager,
{'manager': gmgr, 'share': self.share})
gmgr.get_gluster_vol_option.assert_called_once_with(NFS_EXPORT_VOL)
gmgr.get_vol_option.assert_called_once_with(NFS_EXPORT_VOL)
def test_check_for_setup_error(self):
self._driver.check_for_setup_error()
@ -225,13 +221,13 @@ class GlusterNFSHelperTestCase(test.TestCase):
@ddt.unpack
def test_get_export_dir_dict(self, output_str, expected):
self.mock_object(self._helper.gluster_manager,
'get_gluster_vol_option',
'get_vol_option',
mock.Mock(return_value=output_str))
ret = self._helper._get_export_dir_dict()
self.assertEqual(expected, ret)
(self._helper.gluster_manager.get_gluster_vol_option.
(self._helper.gluster_manager.get_vol_option.
assert_called_once_with(NFS_EXPORT_DIR))
def test_manage_access_bad_access_type(self):
@ -268,8 +264,7 @@ class GlusterNFSHelperTestCase(test.TestCase):
'fakename': ['10.0.0.2'],
}
export_str = '/example.com(10.0.0.1),/fakename(10.0.0.2|10.0.0.1)'
args = ('volume', 'set', self._helper.gluster_manager.volume,
NFS_EXPORT_DIR, export_str)
args = (NFS_EXPORT_DIR, export_str)
self.mock_object(self._helper, '_get_export_dir_dict',
mock.Mock(return_value=export_dir_dict))
@ -279,8 +274,8 @@ class GlusterNFSHelperTestCase(test.TestCase):
self.assertIsNone(ret)
self._helper._get_export_dir_dict.assert_called_once_with()
self._helper.gluster_manager.gluster_call.assert_called_once_with(
*args, log=mock.ANY)
self._helper.gluster_manager.set_vol_option.assert_called_once_with(
*args)
def test_manage_access_removing_last_entry(self):
@ -288,8 +283,7 @@ class GlusterNFSHelperTestCase(test.TestCase):
d.pop(key)
access = fake_share.fake_access()
args = ('volume', 'reset', self._helper.gluster_manager.volume,
NFS_EXPORT_DIR)
args = (NFS_EXPORT_DIR, None)
export_dir_dict = {'fakename': ['10.0.0.1']}
self.mock_object(self._helper, '_get_export_dir_dict',
mock.Mock(return_value=export_dir_dict))
@ -300,8 +294,8 @@ class GlusterNFSHelperTestCase(test.TestCase):
self.assertIsNone(ret)
self._helper._get_export_dir_dict.assert_called_once_with()
self._helper.gluster_manager.gluster_call.assert_called_once_with(
*args, log=mock.ANY)
self._helper.gluster_manager.set_vol_option.assert_called_once_with(
*args)
def test_allow_access_with_share_having_noaccess(self):
access = fake_share.fake_access()
@ -315,9 +309,8 @@ class GlusterNFSHelperTestCase(test.TestCase):
self._helper.allow_access(None, share, access)
self._helper._get_export_dir_dict.assert_called_once_with()
self._helper.gluster_manager.gluster_call.assert_called_once_with(
'volume', 'set', self._helper.gluster_manager.volume,
NFS_EXPORT_DIR, export_str, log=mock.ANY)
self._helper.gluster_manager.set_vol_option.assert_called_once_with(
NFS_EXPORT_DIR, export_str)
def test_allow_access_with_share_having_access(self):
access = fake_share.fake_access()
@ -330,7 +323,7 @@ class GlusterNFSHelperTestCase(test.TestCase):
self._helper.allow_access(None, share, access)
self._helper._get_export_dir_dict.assert_called_once_with()
self.assertFalse(self._helper.gluster_manager.gluster_call.called)
self.assertFalse(self._helper.gluster_manager.set_vol_option.called)
def test_deny_access_with_share_having_noaccess(self):
access = fake_share.fake_access()
@ -343,7 +336,7 @@ class GlusterNFSHelperTestCase(test.TestCase):
self._helper.deny_access(None, share, access)
self._helper._get_export_dir_dict.assert_called_once_with()
self.assertFalse(self._helper.gluster_manager.gluster_call.called)
self.assertFalse(self._helper.gluster_manager.set_vol_option.called)
def test_deny_access_with_share_having_access(self):
access = fake_share.fake_access()
@ -353,8 +346,7 @@ class GlusterNFSHelperTestCase(test.TestCase):
'fakename': ['10.0.0.1'],
}
export_str = '/example.com(10.0.0.1)'
args = ('volume', 'set', self._helper.gluster_manager.volume,
NFS_EXPORT_DIR, export_str)
args = (NFS_EXPORT_DIR, export_str)
self.mock_object(self._helper, '_get_export_dir_dict',
mock.Mock(return_value=export_dir_dict))
self._helper.gluster_manager.path = '/fakename'
@ -362,8 +354,8 @@ class GlusterNFSHelperTestCase(test.TestCase):
self._helper.deny_access(None, share, access)
self._helper._get_export_dir_dict.assert_called_once_with()
self._helper.gluster_manager.gluster_call.assert_called_once_with(
*args, log=mock.ANY)
self._helper.gluster_manager.set_vol_option.assert_called_once_with(
*args)
@ddt.ddt
@ -385,13 +377,13 @@ class GlusterNFSVolHelperTestCase(test.TestCase):
@ddt.unpack
def test_get_vol_exports(self, output_str, expected):
self.mock_object(self._helper.gluster_manager,
'get_gluster_vol_option',
'get_vol_option',
mock.Mock(return_value=output_str))
ret = self._helper._get_vol_exports()
self.assertEqual(expected, ret)
(self._helper.gluster_manager.get_gluster_vol_option.
(self._helper.gluster_manager.get_vol_option.
assert_called_once_with(NFS_RPC_AUTH_ALLOW))
def test_manage_access_bad_access_type(self):
@ -431,13 +423,11 @@ class GlusterNFSVolHelperTestCase(test.TestCase):
self.assertIsNone(ret)
self._helper._get_vol_exports.assert_called_once_with()
export_str = '10.0.0.2,10.0.0.1'
argseq = (('volume', 'set', self._helper.gluster_manager.volume,
NFS_RPC_AUTH_ALLOW, export_str),
('volume', 'reset', self._helper.gluster_manager.volume,
NFS_RPC_AUTH_REJECT))
argseq = ((NFS_RPC_AUTH_ALLOW, export_str),
(NFS_RPC_AUTH_REJECT, None))
self.assertEqual(
[mock.call(*a, log=mock.ANY) for a in argseq],
self._helper.gluster_manager.gluster_call.call_args_list)
[mock.call(*a) for a in argseq],
self._helper.gluster_manager.set_vol_option.call_args_list)
def test_manage_access_removing_last_entry(self):
@ -454,13 +444,11 @@ class GlusterNFSVolHelperTestCase(test.TestCase):
self.assertIsNone(ret)
self._helper._get_vol_exports.assert_called_once_with()
argseq = (('volume', 'reset', self._helper.gluster_manager.volume,
NFS_RPC_AUTH_ALLOW),
('volume', 'set', self._helper.gluster_manager.volume,
NFS_RPC_AUTH_REJECT, '*'))
argseq = ((NFS_RPC_AUTH_ALLOW, None),
(NFS_RPC_AUTH_REJECT, '*'))
self.assertEqual(
[mock.call(*a, log=mock.ANY) for a in argseq],
self._helper.gluster_manager.gluster_call.call_args_list)
[mock.call(*a) for a in argseq],
self._helper.gluster_manager.set_vol_option.call_args_list)
def test_allow_access_with_share_having_noaccess(self):
access = fake_share.fake_access()
@ -473,13 +461,11 @@ class GlusterNFSVolHelperTestCase(test.TestCase):
self._helper._get_vol_exports.assert_called_once_with()
export_str = '10.0.0.2,10.0.0.1'
argseq = (('volume', 'set', self._helper.gluster_manager.volume,
NFS_RPC_AUTH_ALLOW, export_str),
('volume', 'reset', self._helper.gluster_manager.volume,
NFS_RPC_AUTH_REJECT))
argseq = ((NFS_RPC_AUTH_ALLOW, export_str),
(NFS_RPC_AUTH_REJECT, None))
self.assertEqual(
[mock.call(*a, log=mock.ANY) for a in argseq],
self._helper.gluster_manager.gluster_call.call_args_list)
[mock.call(*a) for a in argseq],
self._helper.gluster_manager.set_vol_option.call_args_list)
def test_allow_access_with_share_having_access(self):
access = fake_share.fake_access()
@ -491,7 +477,7 @@ class GlusterNFSVolHelperTestCase(test.TestCase):
self._helper.allow_access(None, share, access)
self._helper._get_vol_exports.assert_called_once_with()
self.assertFalse(self._helper.gluster_manager.gluster_call.called)
self.assertFalse(self._helper.gluster_manager.set_vol_option.called)
def test_deny_access_with_share_having_noaccess(self):
access = fake_share.fake_access()
@ -503,7 +489,7 @@ class GlusterNFSVolHelperTestCase(test.TestCase):
self._helper.deny_access(None, share, access)
self._helper._get_vol_exports.assert_called_once_with()
self.assertFalse(self._helper.gluster_manager.gluster_call.called)
self.assertFalse(self._helper.gluster_manager.set_vol_option.called)
def test_deny_access_with_share_having_access(self):
access = fake_share.fake_access()
@ -516,13 +502,11 @@ class GlusterNFSVolHelperTestCase(test.TestCase):
self._helper._get_vol_exports.assert_called_once_with()
export_str = '10.0.0.2'
argseq = (('volume', 'set', self._helper.gluster_manager.volume,
NFS_RPC_AUTH_ALLOW, export_str),
('volume', 'reset', self._helper.gluster_manager.volume,
NFS_RPC_AUTH_REJECT))
argseq = ((NFS_RPC_AUTH_ALLOW, export_str),
(NFS_RPC_AUTH_REJECT, None))
self.assertEqual(
[mock.call(*a, log=mock.ANY) for a in argseq],
self._helper.gluster_manager.gluster_call.call_args_list)
[mock.call(*a) for a in argseq],
self._helper.gluster_manager.set_vol_option.call_args_list)
class GaneshaNFSHelperTestCase(test.TestCase):

View File

@ -98,74 +98,65 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.assertEqual(('GLUSTERFS', ),
self._driver.supported_protocols)
@ddt.data(True, False)
def test_setup_via_manager(self, has_dynauth):
def test_setup_via_manager(self):
gmgr = mock.Mock()
if has_dynauth:
_gluster_call = lambda *args, **kwargs: None
else:
def _gluster_call(*args, **kwargs):
if kwargs.get('raw_error'):
raise exception.ProcessExecutionError(exit_code=1)
gmgr.gluster_call = mock.Mock(side_effect=_gluster_call)
gmgr.gluster_call = mock.Mock()
gmgr.set_vol_option = mock.Mock()
gmgr.volume = 'fakevol'
gmgr.export = 'fakehost:/fakevol'
gmgr.get_gluster_vol_option = mock.Mock(
gmgr.get_vol_option = mock.Mock(
return_value='glusterfs-server-name,some-other-name')
share = mock.Mock()
settings = (
('nfs.export-volumes', False, {}),
('client.ssl', True, {}),
('server.ssl', True, {}),
('server.dynamic-auth', True, {'ignore_failure': True}),
)
call_args = (
('volume', 'stop', 'fakevol', '--mode=script', {'log': mock.ANY}),
('volume', 'start', 'fakevol', {'log': mock.ANY}),
)
ret = self._driver._setup_via_manager({'manager': gmgr,
'share': share})
gmgr.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
args = (
('volume', 'set', 'fakevol', 'nfs.export-volumes', 'off',
{'log': mock.ANY}),
('volume', 'set', 'fakevol', 'client.ssl', 'on',
{'log': mock.ANY}),
('volume', 'set', 'fakevol', 'server.ssl', 'on',
{'log': mock.ANY}),
('volume', 'set', 'fakevol', 'server.dynamic-auth', 'on',
{'raw_error': True}),
('volume', 'stop', 'fakevol', '--mode=script', {'log': mock.ANY}),
('volume', 'start', 'fakevol', {'log': mock.ANY}))
gmgr.get_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr.set_vol_option.assert_has_calls(
[mock.call(*a[:-1], **a[-1]) for a in settings])
gmgr.gluster_call.assert_has_calls(
[mock.call(*a[:-1], **a[-1]) for a in args])
[mock.call(*a[:-1], **a[-1]) for a in call_args])
self.assertEqual(ret, gmgr.export)
def test_setup_via_manager_with_parent(self):
gmgr = mock.Mock()
gmgr.gluster_call = mock.Mock()
gmgr.set_vol_option = mock.Mock()
gmgr.volume = 'fakevol'
gmgr.export = 'fakehost:/fakevol'
gmgr_parent = mock.Mock()
gmgr_parent.get_gluster_vol_option = mock.Mock(
gmgr_parent.get_vol_option = mock.Mock(
return_value=(
'glusterfs-server-name,some-other-name,manila-host.com'))
share = mock.Mock()
share_parent = mock.Mock()
settings = (
('auth.ssl-allow',
'glusterfs-server-name,manila-host.com', {}),
('nfs.export-volumes', False, {}),
('client.ssl', True, {}),
('server.ssl', True, {}),
('server.dynamic-auth', True, {'ignore_failure': True}),
)
ret = self._driver._setup_via_manager(
{'manager': gmgr, 'share': share},
{'manager': gmgr_parent, 'share': share_parent})
gmgr_parent.get_gluster_vol_option.assert_called_once_with(
gmgr_parent.get_vol_option.assert_called_once_with(
'auth.ssl-allow')
args = (
('volume', 'set', 'fakevol', 'auth.ssl-allow',
'glusterfs-server-name,manila-host.com', {'log': mock.ANY}),
('volume', 'set', 'fakevol', 'nfs.export-volumes', 'off',
{'log': mock.ANY}),
('volume', 'set', 'fakevol', 'client.ssl', 'on',
{'log': mock.ANY}),
('volume', 'set', 'fakevol', 'server.ssl', 'on',
{'log': mock.ANY}),
('volume', 'set', 'fakevol', 'server.dynamic-auth', 'on',
{'raw_error': True}))
gmgr.gluster_call.assert_has_calls(
[mock.call(*a[:-1], **a[-1]) for a in args])
gmgr.set_vol_option.assert_has_calls(
[mock.call(*a[:-1], **a[-1]) for a in settings])
self.assertEqual(ret, gmgr.export)
@ddt.data(True, False)
@ -180,38 +171,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
else:
share_mgr_parent = None
gmgr_queried = gmgr
gmgr_queried.get_gluster_vol_option = mock.Mock(return_value='')
gmgr_queried.get_vol_option = mock.Mock(return_value='')
self.assertRaises(exception.GlusterfsException,
self._driver._setup_via_manager,
{'share': share, 'manager': gmgr},
share_mgr_parent=share_mgr_parent)
gmgr_queried.get_gluster_vol_option.assert_called_once_with(
gmgr_queried.get_vol_option.assert_called_once_with(
'auth.ssl-allow')
@ddt.data({'trouble': exception.ProcessExecutionError,
'trouble_kw': {'exit_code': 2},
'_exception': exception.GlusterfsException},
{'trouble': RuntimeError, 'trouble_kw': {},
'_exception': RuntimeError})
@ddt.unpack
def test_setup_via_manager_exception(self, trouble, trouble_kw,
_exception):
share = mock.Mock()
gmgr = mock.Mock()
def raise_exception(*args, **kwargs):
if kwargs.get('raw_error'):
raise trouble(**trouble_kw)
gmgr.gluster_call = mock.Mock(side_effect=raise_exception)
gmgr.get_gluster_vol_option = mock.Mock()
self.assertRaises(
_exception, self._driver._setup_via_manager,
{'share': share, 'manager': gmgr})
def test_snapshots_are_supported(self):
self.assertTrue(self._driver.snapshots_are_supported)
@ -219,32 +188,34 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
self.mock_object(gmgr1, 'get_gluster_vol_option',
self.mock_object(gmgr1, 'get_vol_option',
mock.Mock(return_value='some.common.name'))
test_args = ('volume', 'set', 'gv1', 'auth.ssl-allow',
self.mock_object(gmgr1, 'set_vol_option')
test_args = ('auth.ssl-allow',
'some.common.name,' + access['access_to'])
self._driver.layout.gluster_used_vols = set([self.glusterfs_target1])
self._driver._allow_access_via_manager(gmgr1, self._context,
self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr1.gluster_call.assert_called_once_with(*test_args, log=mock.ANY)
gmgr1.get_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr1.set_vol_option.assert_called_once_with(*test_args)
def test_allow_access_via_manager_with_share_having_access(self):
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
self.mock_object(
gmgr1, 'get_gluster_vol_option',
gmgr1, 'get_vol_option',
mock.Mock(return_value='some.common.name,' + access['access_to']))
self.mock_object(gmgr1, 'set_vol_option')
self._driver.layout.gluster_used_vols = set([self.glusterfs_target1])
self._driver._allow_access_via_manager(gmgr1, self._context,
self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertFalse(gmgr1.gluster_call.called)
gmgr1.get_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertFalse(gmgr1.set_vol_option.called)
def test_allow_access_via_manager_invalid_access_type(self):
access = {'access_type': 'invalid', 'access_to': 'client.example.com'}
@ -263,25 +234,25 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
def _get_gluster_vol_option(opt):
def _get_vol_option(opt):
if opt == 'auth.ssl-allow':
return('some.common.name,' + access['access_to'])
elif opt == 'server.dynamic-auth':
return trueish
self.mock_object(
gmgr1, 'get_gluster_vol_option',
mock.Mock(side_effect=_get_gluster_vol_option))
gmgr1, 'get_vol_option',
mock.Mock(side_effect=_get_vol_option))
self.mock_object(gmgr1, 'set_vol_option')
self._driver.layout.gluster_used_vols = set([self.glusterfs_target1])
self._driver._deny_access_via_manager(gmgr1, self._context,
self.share1, access)
gmgr1.get_gluster_vol_option.assert_has_calls(
gmgr1.get_vol_option.assert_has_calls(
[mock.call(a) for a in ('auth.ssl-allow', 'server.dynamic-auth')])
test_args = ('volume', 'set', 'gv1', 'auth.ssl-allow',
'some.common.name')
gmgr1.gluster_call.assert_called_once_with(*test_args, log=mock.ANY)
test_args = ('auth.ssl-allow', 'some.common.name')
gmgr1.set_vol_option.assert_called_once_with(*test_args)
self.assertFalse(common._restart_gluster_vol.called)
@ddt.data('off', None, 'strangelove')
@ -291,25 +262,25 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
def _get_gluster_vol_option(opt):
def _get_vol_option(opt):
if opt == 'auth.ssl-allow':
return('some.common.name,' + access['access_to'])
elif opt == 'server.dynamic-auth':
return falseish
self.mock_object(
gmgr1, 'get_gluster_vol_option',
mock.Mock(side_effect=_get_gluster_vol_option))
gmgr1, 'get_vol_option',
mock.Mock(side_effect=_get_vol_option))
self.mock_object(gmgr1, 'set_vol_option')
self._driver.layout.gluster_used_vols = set([self.glusterfs_target1])
self._driver._deny_access_via_manager(gmgr1, self._context,
self.share1, access)
gmgr1.get_gluster_vol_option.assert_has_calls(
gmgr1.get_vol_option.assert_has_calls(
[mock.call(a) for a in ('auth.ssl-allow', 'server.dynamic-auth')])
test_args = ('volume', 'set', 'gv1', 'auth.ssl-allow',
'some.common.name')
gmgr1.gluster_call.assert_called_once_with(*test_args, log=mock.ANY)
test_args = ('auth.ssl-allow', 'some.common.name')
gmgr1.set_vol_option.assert_called_once_with(*test_args)
common._restart_gluster_vol.assert_called_once_with(gmgr1)
def test_deny_access_via_manager_with_share_having_no_access(self):
@ -317,15 +288,16 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
self.mock_object(gmgr1, 'get_gluster_vol_option',
self.mock_object(gmgr1, 'get_vol_option',
mock.Mock(return_value='some.common.name'))
self.mock_object(gmgr1, 'set_vol_option')
self._driver.layout.gluster_used_vols = set([self.glusterfs_target1])
self._driver._deny_access_via_manager(gmgr1, self._context,
self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertFalse(gmgr1.gluster_call.called)
gmgr1.get_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertFalse(gmgr1.set_vol_option.called)
self.assertFalse(common._restart_gluster_vol.called)
def test_deny_access_via_manager_invalid_access_type(self):