Merge "glusterfs_native: use dynamic-auth option if available"

This commit is contained in:
Jenkins 2015-10-01 14:15:55 +00:00 committed by Gerrit Code Review
commit 38220a2d7c
2 changed files with 130 additions and 36 deletions

View File

@ -45,6 +45,7 @@ AUTH_SSL_ALLOW = 'auth.ssl-allow'
CLIENT_SSL = 'client.ssl'
NFS_EXPORT_VOL = 'nfs.export-volumes'
SERVER_SSL = 'server.ssl'
DYNAMIC_AUTH = 'dynamic-auth'
class GlusterfsNativeShareDriver(driver.ExecuteMixin,
@ -119,29 +120,41 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
'pattern1': glusterfs_server_CN_pattern,
'pattern2': manila_host_CN_pattern})
access_to = ','.join(filter(regex.match, old_access_list))
gluster_actions.append(('set', AUTH_SSL_ALLOW, access_to))
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, 'off'), (CLIENT_SSL, 'on'), (SERVER_SSL, 'on'),
(DYNAMIC_AUTH, 'on')
):
gluster_actions.append(('set', option, value))
gluster_actions.append((option, value))
for action in gluster_actions:
try:
gluster_mgr.gluster_call(
'volume', action[0], gluster_mgr.volume, *action[1:])
'volume', 'set', gluster_mgr.volume, *action)
except exception.ProcessExecutionError as exc:
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)
if action[0] == DYNAMIC_AUTH and 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)
if not gluster_mgr_parent:
# TODO(deepakcs) Remove this once ssl options can be
# set dynamically.
# SSL enablement requires a fresh volume start
# to take effect
if gluster_mgr_parent:
# in this case the volume is not started
# yet (will only be started after this func
# returns), so we have nothing to do here
pass
else:
common._restart_gluster_vol(gluster_mgr)
return gluster_mgr.export
@ -189,10 +202,6 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
LOG.error(msg)
raise exception.GlusterfsException(msg)
# TODO(deepakcs) Remove this once ssl options can be
# set dynamically.
common._restart_gluster_vol(gluster_mgr)
@utils.synchronized("glusterfs_native_access", external=False)
def _deny_access_via_manager(self, gluster_mgr, context, share, access,
share_server=None):
@ -233,9 +242,25 @@ class GlusterfsNativeShareDriver(driver.ExecuteMixin,
LOG.error(msg)
raise exception.GlusterfsException(msg)
# TODO(deepakcs) Remove this once ssl options can be
# set dynamically.
common._restart_gluster_vol(gluster_mgr)
try:
dynauth = gluster_mgr.get_gluster_vol_option(DYNAMIC_AUTH) or 'off'
except exception.ProcessExecutionError as exc:
if exc.exit_code == 1:
# dynamic auth is not supported by gluster backend
dynauth = 'off'
else:
# unexpected failure
msg = (_("Error in querying gluster volume."
"Volume: %(volname)s, Option: %(option)s, "
"access_to: %(access_to)s, Error: %(error)s") %
{'volname': gluster_mgr.volume,
'option': AUTH_SSL_ALLOW, 'access_to': access_to,
'error': exc.stderr})
LOG.error(msg)
raise exception.GlusterfsException(msg)
# 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)
def _update_share_stats(self):
"""Send stats info for the GlusterFS volume."""

View File

@ -115,6 +115,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
('volume', 'set', 'fakevol', 'nfs.export-volumes', 'off'),
('volume', 'set', 'fakevol', 'client.ssl', 'on'),
('volume', 'set', 'fakevol', 'server.ssl', 'on'),
('volume', 'set', 'fakevol', 'dynamic-auth', 'on'),
('volume', 'stop', 'fakevol', '--mode=script'),
('volume', 'start', 'fakevol'))
gmgr.gluster_call.assert_has_calls([mock.call(*a) for a in args])
@ -143,7 +144,8 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
'glusterfs-server-name,manila-host.com'),
('volume', 'set', 'fakevol', 'nfs.export-volumes', 'off'),
('volume', 'set', 'fakevol', 'client.ssl', 'on'),
('volume', 'set', 'fakevol', 'server.ssl', 'on'))
('volume', 'set', 'fakevol', 'server.ssl', 'on'),
('volume', 'set', 'fakevol', 'dynamic-auth', 'on'))
gmgr.gluster_call.assert_has_calls([mock.call(*a) for a in args])
self.assertEqual(ret, gmgr.export)
@ -186,7 +188,6 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.assertTrue(self._driver.snapshots_are_supported)
def test_allow_access_via_manager(self):
self.mock_object(common, '_restart_gluster_vol', mock.Mock())
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
@ -201,10 +202,8 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr1.gluster_call.assert_called_once_with(*test_args)
common._restart_gluster_vol.assert_called_once_with(gmgr1)
def test_allow_access_via_manager_with_share_having_access(self):
self.mock_object(common, '_restart_gluster_vol', mock.Mock())
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
@ -218,10 +217,8 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.share1, access)
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
self.assertFalse(gmgr1.gluster_call.called)
self.assertFalse(common._restart_gluster_vol.called)
def test_allow_access_via_manager_invalid_access_type(self):
self.mock_object(common, '_restart_gluster_vol', mock.Mock())
access = {'access_type': 'invalid', 'access_to': 'client.example.com'}
expected_exec = []
@ -229,7 +226,6 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self._driver._allow_access_via_manager,
self.gmgr1, self._context, self.share1, access)
self.assertFalse(common._restart_gluster_vol.called)
self.assertEqual(expected_exec, fake_utils.fake_execute_get_log())
def test_allow_access_via_manager_excp(self):
@ -241,7 +237,6 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
if (args == test_args):
raise exception.ProcessExecutionError()
self.mock_object(common, '_restart_gluster_vol', mock.Mock())
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
self.mock_object(gmgr1, 'get_gluster_vol_option',
@ -256,22 +251,60 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
gmgr1.get_gluster_vol_option.assert_called_once_with('auth.ssl-allow')
gmgr1.gluster_call.assert_called_once_with(*test_args)
self.assertFalse(common._restart_gluster_vol.called)
def test_deny_access_via_manager(self):
@ddt.data('on', '1', 'Yes', 'TRUE', 'enable')
def test_deny_access_via_manager(self, trueish):
self.mock_object(common, '_restart_gluster_vol', mock.Mock())
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
def _get_gluster_vol_option(opt):
if opt == 'auth.ssl-allow':
return('some.common.name,' + access['access_to'])
elif opt == 'dynamic-auth':
return trueish
self.mock_object(
gmgr1, 'get_gluster_vol_option',
mock.Mock(return_value='some.common.name,' + access['access_to']))
mock.Mock(side_effect=_get_gluster_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')
gmgr1.get_gluster_vol_option.assert_has_calls(
[mock.call(a) for a in ('auth.ssl-allow', 'dynamic-auth')])
test_args = ('volume', 'set', 'gv1', 'auth.ssl-allow',
'some.common.name')
gmgr1.gluster_call.assert_called_once_with(*test_args)
self.assertFalse(common._restart_gluster_vol.called)
@ddt.data('off', None, 'strangelove', '!')
def test_deny_access_via_manager_no_dyn_auth(self, falseish):
self.mock_object(common, '_restart_gluster_vol', mock.Mock())
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
def _get_gluster_vol_option(opt):
if opt == 'auth.ssl-allow':
return('some.common.name,' + access['access_to'])
elif opt == 'dynamic-auth':
if falseish == '!':
raise exception.ProcessExecutionError(exit_code=1)
return falseish
self.mock_object(
gmgr1, 'get_gluster_vol_option',
mock.Mock(side_effect=_get_gluster_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(
[mock.call(a) for a in ('auth.ssl-allow', 'dynamic-auth')])
test_args = ('volume', 'set', 'gv1', 'auth.ssl-allow',
'some.common.name')
gmgr1.gluster_call.assert_called_once_with(*test_args)
@ -303,14 +336,18 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.assertFalse(common._restart_gluster_vol.called)
def test_deny_access_via_manager_excp(self):
@ddt.data({'trouble': exception.ProcessExecutionError,
'_exception': exception.GlusterfsException},
{'trouble': RuntimeError, '_exception': RuntimeError})
@ddt.unpack
def test_deny_access_via_manager_excp(self, trouble, _exception):
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
test_args = ('volume', 'set', 'gv1', 'auth.ssl-allow',
'some.common.name')
def raise_exception(*args, **kwargs):
if (args == test_args):
raise exception.ProcessExecutionError()
raise trouble()
self.mock_object(common, '_restart_gluster_vol', mock.Mock())
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
@ -323,7 +360,7 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
self.mock_object(gmgr1, 'gluster_call',
mock.Mock(side_effect=raise_exception))
self.assertRaises(exception.GlusterfsException,
self.assertRaises(_exception,
self._driver._deny_access_via_manager, gmgr1,
self._context, self.share1, access)
@ -331,6 +368,38 @@ class GlusterfsNativeShareDriverTestCase(test.TestCase):
gmgr1.gluster_call.assert_called_once_with(*test_args)
self.assertFalse(common._restart_gluster_vol.called)
@ddt.data({'trouble': (exception.ProcessExecutionError, {'exit_code': 2}),
'_exception': exception.GlusterfsException},
{'trouble': (RuntimeError, {}), '_exception': RuntimeError})
@ddt.unpack
def test_deny_access_via_manager_dyn_auth_fail(self, trouble, _exception):
self.mock_object(common, '_restart_gluster_vol', mock.Mock())
access = {'access_type': 'cert', 'access_to': 'client.example.com'}
gmgr1 = common.GlusterManager(self.glusterfs_target1, self._execute,
None, None)
def _get_gluster_vol_option(opt):
if opt == 'auth.ssl-allow':
return('some.common.name,' + access['access_to'])
elif opt == 'dynamic-auth':
raise trouble[0](**trouble[1])
self.mock_object(
gmgr1, 'get_gluster_vol_option',
mock.Mock(side_effect=_get_gluster_vol_option))
self._driver.layout.gluster_used_vols = set([self.glusterfs_target1])
self.assertRaises(_exception,
self._driver._deny_access_via_manager, gmgr1,
self._context, self.share1, access)
gmgr1.get_gluster_vol_option.assert_has_calls(
[mock.call(a) for a in ('auth.ssl-allow', 'dynamic-auth')])
test_args = ('volume', 'set', 'gv1', 'auth.ssl-allow',
'some.common.name')
gmgr1.gluster_call.assert_called_once_with(*test_args)
self.assertFalse(common._restart_gluster_vol.called)
def test_update_share_stats(self):
self._driver._update_share_stats()