From c15aec017b2ebe666ccfee4cbe088bc723d3ede6 Mon Sep 17 00:00:00 2001 From: zhongjun Date: Fri, 5 Jun 2015 06:33:26 +0800 Subject: [PATCH] Huawei manila driver support Read-Only share - Change allow_access function: Add access_level parameter to setting 'rw' and 'ro'. - Add unit test. Change-Id: I9f9202242ec89c0dad27befce8992481e298d407 Implements blueprint huawei-driver-read-only-share --- manila/share/drivers/huawei/constants.py | 5 + manila/share/drivers/huawei/v3/connection.py | 37 +++-- manila/share/drivers/huawei/v3/helper.py | 7 +- .../share/drivers/huawei/test_huawei_nas.py | 133 +++++++++++++++++- 4 files changed, 166 insertions(+), 16 deletions(-) diff --git a/manila/share/drivers/huawei/constants.py b/manila/share/drivers/huawei/constants.py index 1e4ebd24f7..075ba02a7c 100644 --- a/manila/share/drivers/huawei/constants.py +++ b/manila/share/drivers/huawei/constants.py @@ -21,3 +21,8 @@ DEFAULT_TIMEOUT = 60 MSG_SNAPSHOT_NOT_FOUND = 1073754118 IP_ALLOCATIONS = 0 SOCKET_TIMEOUT = 720 + +ACCESS_NFS_RW = "1" +ACCESS_NFS_RO = "0" +ACCESS_CIFS_RW = "5" +ACCESS_CIFS_RO = "0" diff --git a/manila/share/drivers/huawei/v3/connection.py b/manila/share/drivers/huawei/v3/connection.py index e91a4f0a41..8dedaa8114 100644 --- a/manila/share/drivers/huawei/v3/connection.py +++ b/manila/share/drivers/huawei/v3/connection.py @@ -18,6 +18,7 @@ import time from oslo_log import log from oslo_utils import units +from manila.common import constants as common_constants from manila import exception from manila.i18n import _, _LI, _LW from manila.share.drivers.huawei import base as driver @@ -295,14 +296,32 @@ class V3StorageConnection(driver.HuaweiBase): share_name = share['name'] share_type = self.helper._get_share_type(share_proto) access_type = access['access_type'] - if share_proto == 'NFS' and access_type != 'ip': - message = _('Only IP access type is allowed for NFS shares.') - raise exception.InvalidShareAccess(reason=message) - elif share_proto == 'CIFS' and access_type != 'user': - message = _('Only USER access type is allowed for CIFS shares.') - raise exception.InvalidShareAccess(reason=message) + access_level = access['access_level'] - access_to = access['access_to'] + if access_level not in common_constants.ACCESS_LEVELS: + raise exception.InvalidShareAccess( + reason=(_('Unsupported level of access was provided - %s') % + access_level)) + + if share_proto == 'NFS': + if access_type == 'ip': + if access_level == common_constants.ACCESS_LEVEL_RW: + access_level = constants.ACCESS_NFS_RW + else: + access_level = constants.ACCESS_NFS_RO + else: + message = _('Only IP access type is allowed for NFS shares.') + raise exception.InvalidShareAccess(reason=message) + elif share_proto == 'CIFS': + if access_type == 'user': + if access_level == common_constants.ACCESS_LEVEL_RW: + access_level = constants.ACCESS_CIFS_RW + else: + access_level = constants.ACCESS_CIFS_RO + else: + message = _('Only USER access type is allowed' + ' for CIFS shares.') + raise exception.InvalidShareAccess(reason=message) share = self.helper._get_share_by_name(share_name, share_type) if not share: @@ -312,7 +331,9 @@ class V3StorageConnection(driver.HuaweiBase): raise exception.InvalidShareAccess(reason=err_msg) share_id = share['ID'] - self.helper._allow_access_rest(share_id, access_to, share_proto) + access_to = access['access_to'] + self.helper._allow_access_rest(share_id, access_to, + share_proto, access_level) def allocate_container(self, share): """Creates filesystem associated to share by name.""" diff --git a/manila/share/drivers/huawei/v3/helper.py b/manila/share/drivers/huawei/v3/helper.py index 48341300dc..721ce8dfb5 100644 --- a/manila/share/drivers/huawei/v3/helper.py +++ b/manila/share/drivers/huawei/v3/helper.py @@ -366,7 +366,8 @@ class RestHelper(object): if access_to == item['NAME']: return item['ID'] - def _allow_access_rest(self, share_id, access_to, share_proto): + def _allow_access_rest(self, share_id, access_to, + share_proto, access_level): """Allow access to the share.""" access_type = self._get_share_client_type(share_proto) url = self.url + "/" + access_type @@ -377,7 +378,7 @@ class RestHelper(object): "TYPE": "16409", "NAME": access_to, "PARENTID": share_id, - "ACCESSVAL": "1", + "ACCESSVAL": access_level, "SYNC": "0", "ALLSQUASH": "1", "ROOTSQUASH": "0", @@ -386,7 +387,7 @@ class RestHelper(object): access = { "NAME": access_to, "PARENTID": share_id, - "PERMISSION": "5", + "PERMISSION": access_level, "DOMAINTYPE": "2", } data = jsonutils.dumps(access) diff --git a/manila/tests/share/drivers/huawei/test_huawei_nas.py b/manila/tests/share/drivers/huawei/test_huawei_nas.py index a0e127da72..9043fe027a 100644 --- a/manila/tests/share/drivers/huawei/test_huawei_nas.py +++ b/manila/tests/share/drivers/huawei/test_huawei_nas.py @@ -73,6 +73,51 @@ def filesystem(method, data, fs_status_flag): return (data, extend_share_flag) +def allow_access(type, method, data): + allow_ro_flag = False + allow_rw_flag = False + access_nfs = { + "TYPE": "16409", + "NAME": "1.2.3.4", + "PARENTID": "1", + "ACCESSVAL": "0", + "SYNC": "0", + "ALLSQUASH": "1", + "ROOTSQUASH": "0", + } + access_nfs_ro_data = jsonutils.dumps(access_nfs) + access_nfs["NAME"] = "100.112.0.1" + access_nfs["ACCESSVAL"] = "1" + access_nfs_rw_data = jsonutils.dumps(access_nfs) + + access_cifs = { + "NAME": "user_name", + "PARENTID": "2", + "PERMISSION": "0", + "DOMAINTYPE": "2", + } + access_cifs_ro_data = jsonutils.dumps(access_cifs) + + access_cifs["PERMISSION"] = "5" + access_cifs_rw_data = jsonutils.dumps(access_cifs) + + if method != "POST": + data = """{"error":{"code":31755596}}""" + return data + + if ((data == access_nfs_ro_data and type == "NFS") + or (data == access_cifs_ro_data and type == "CIFS")): + allow_ro_flag = True + data = """{"error":{"code":0}}""" + elif ((data == access_nfs_rw_data and type == 'NFS') + or (data == access_cifs_rw_data and type == 'CIFS')): + allow_rw_flag = True + data = """{"error":{"code":0}}""" + else: + data = """{"error":{"code":31755596}}""" + return (data, allow_ro_flag, allow_rw_flag) + + class FakeHuaweiNasHelper(helper.RestHelper): def __init__(self, *args, **kwargs): @@ -91,6 +136,8 @@ class FakeHuaweiNasHelper(helper.RestHelper): self.share_exist = True self.service_nfs_status_flag = True self.create_share_data_flag = False + self.allow_ro_flag = False + self.allow_rw_flag = False self.extend_share_flag = False def _change_file_mode(self, filepath): @@ -179,9 +226,14 @@ class FakeHuaweiNasHelper(helper.RestHelper): data = """{"error":{"code":0}}""" self.delete_flag = True - if url == "NFS_SHARE_AUTH_CLIENT"\ - or url == "CIFS_SHARE_AUTH_CLIENT": - data = """{"error":{"code":0}}""" + if url == "NFS_SHARE_AUTH_CLIENT": + data, self.allow_ro_flag, self.allow_rw_flag = \ + allow_access('NFS', method, data) + self.allow_flag = True + + if url == "CIFS_SHARE_AUTH_CLIENT": + data, self.allow_ro_flag, self.allow_rw_flag = \ + allow_access('CIFS', method, data) self.allow_flag = True if url == "FSSNAPSHOT?TYPE=48&PARENTID=4"\ @@ -327,6 +379,17 @@ class HuaweiShareDriverTestCase(test.TestCase): 'share_server_id': 'fake-share-srv-id', } + self.share_proto_fail = { + 'id': 'fake_uuid', + 'project_id': 'fake_tenant_id', + 'display_name': 'fake', + 'name': 'share-fake-uuid', + 'size': 1, + 'share_proto': 'proto_fail', + 'share_network_id': 'fake_net_id', + 'share_server_id': 'fake-share-srv-id', + } + self.share_cifs = { 'id': 'fake_uuid', 'project_id': 'fake_tenant_id', @@ -371,11 +434,13 @@ class HuaweiShareDriverTestCase(test.TestCase): self.access_ip = { 'access_type': 'ip', 'access_to': '100.112.0.1', + 'access_level': 'rw', } self.access_user = { 'access_type': 'user', 'access_to': 'user_name', + 'access_level': 'rw', } self.share_server = None @@ -677,21 +742,79 @@ class HuaweiShareDriverTestCase(test.TestCase): self.assertEqual(2, capacity['TOTALCAPACITY']) self.assertEqual(1, capacity['CAPACITY']) - def test_allow_access_ip_success(self): + def test_allow_access_proto_fail(self): + self.driver.plugin.helper.login() + self.assertRaises(exception.InvalidInput, + self.driver.allow_access, + self._context, + self.share_proto_fail, + self.access_ip, + self.share_server) + + def test_allow_access_ip_rw_success(self): self.driver.plugin.helper.login() self.allow_flag = False + self.allow_rw_flag = False self.driver.allow_access(self._context, self.share_nfs, self.access_ip, self.share_server) self.assertTrue(self.driver.plugin.helper.allow_flag) + self.assertTrue(self.driver.plugin.helper.allow_rw_flag) + + def test_allow_access_ip_ro_success(self): + access_ro = { + 'access_type': 'ip', + 'access_to': '1.2.3.4', + 'access_level': 'ro', + } - def test_allow_access_user_success(self): self.driver.plugin.helper.login() self.allow_flag = False + self.allow_ro_flag = False + self.driver.allow_access(self._context, + self.share_nfs, + access_ro, + self.share_server) + self.assertTrue(self.driver.plugin.helper.allow_flag) + self.assertTrue(self.driver.plugin.helper.allow_ro_flag) + + def test_allow_access_user_rw_success(self): + self.driver.plugin.helper.login() + self.allow_flag = False + self.allow_rw_flag = False self.driver.allow_access(self._context, self.share_cifs, self.access_user, self.share_server) self.assertTrue(self.driver.plugin.helper.allow_flag) + self.assertTrue(self.driver.plugin.helper.allow_rw_flag) + + def test_allow_access_user_ro_success(self): + access_ro = { + 'access_type': 'user', + 'access_to': 'user_name', + 'access_level': 'ro', + } + + self.driver.plugin.helper.login() + self.allow_flag = False + self.allow_ro_flag = False + self.driver.allow_access(self._context, self.share_cifs, + access_ro, self.share_server) + self.assertTrue(self.driver.plugin.helper.allow_flag) + self.assertTrue(self.driver.plugin.helper.allow_ro_flag) + + def test_allow_access_level_fail(self): + access_fail = { + 'access_type': 'user', + 'access_to': 'user_name', + 'access_level': 'fail', + } + + self.driver.plugin.helper.login() + self.assertRaises(exception.InvalidShareAccess, + self.driver.allow_access, + self._context, self.share_cifs, + access_fail, self.share_server) def test_get_share_client_type_fail(self): share_proto = 'fake_proto'