Merge "gluster*: add proper getter/setters for volume options"
This commit is contained in:
commit
2e9fe58161
@ -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."""
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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...
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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', '')))
|
||||
|
@ -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()
|
||||
|
@ -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())
|
||||
|
@ -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):
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user