Change to share access list API

When we do manila access-list, the 'created_at' and 'updated_at' time
should be shown to the user. And then the user could determine which
is the recent access rule. As the design, the recent access-allow
rule caused the error access-status of share instance.

APIImpact
Closes-Bug: #1682795
Change-Id: Iad6070d60ec77b7de9cc9679cfa7478876084da1
This commit is contained in:
yangweiwei 2017-05-05 17:19:25 +08:00
parent e059726240
commit 5a8c3c11b9
9 changed files with 60 additions and 5 deletions

View File

@ -182,6 +182,8 @@ Response parameters
- state: state - state: state
- access_list: access_list - access_list: access_list
- id: access_rule_id - id: access_rule_id
- created_at: access_rule_created_at
- updated_at: access_rule_updated_at
Response example Response example
---------------- ----------------

View File

@ -98,13 +98,15 @@ REST_API_VERSION_HISTORY = """
* 2.30 - Added cast_rules_to_readonly field to share_instances. * 2.30 - Added cast_rules_to_readonly field to share_instances.
* 2.31 - Convert consistency groups to share groups. * 2.31 - Convert consistency groups to share groups.
* 2.32 - Added mountable snapshots APIs. * 2.32 - Added mountable snapshots APIs.
* 2.33 - Added 'created_at' and 'updated_at' to the response of
access_list API.
""" """
# The minimum and maximum versions of the API supported # The minimum and maximum versions of the API supported
# The default api version request is defined to be the # The default api version request is defined to be the
# minimum version of the API supported. # minimum version of the API supported.
_MIN_API_VERSION = "2.0" _MIN_API_VERSION = "2.0"
_MAX_API_VERSION = "2.32" _MAX_API_VERSION = "2.33"
DEFAULT_API_VERSION = _MIN_API_VERSION DEFAULT_API_VERSION = _MIN_API_VERSION

View File

@ -191,3 +191,7 @@ user documentation.
2.32 2.32
---- ----
Added mountable snapshots APIs. Added mountable snapshots APIs.
2.33
----
Added created_at and updated_at in access_list API.

View File

@ -25,6 +25,7 @@ class ViewBuilder(common.ViewBuilder):
_detail_version_modifiers = [ _detail_version_modifiers = [
"add_access_key", "add_access_key",
"translate_transitional_statuses", "translate_transitional_statuses",
"add_created_at_and_updated_at",
] ]
def list_view(self, request, accesses): def list_view(self, request, accesses):
@ -63,6 +64,11 @@ class ViewBuilder(common.ViewBuilder):
def add_access_key(self, context, access_dict, access): def add_access_key(self, context, access_dict, access):
access_dict['access_key'] = access.get('access_key') access_dict['access_key'] = access.get('access_key')
@common.ViewBuilder.versioned_method("2.33")
def add_created_at_and_updated_at(self, context, access_dict, access):
access_dict['created_at'] = access.get('created_at')
access_dict['updated_at'] = access.get('updated_at')
@common.ViewBuilder.versioned_method("1.0", "2.27") @common.ViewBuilder.versioned_method("1.0", "2.27")
def translate_transitional_statuses(self, context, access_dict, access): def translate_transitional_statuses(self, context, access_dict, access):
"""In 2.28, the per access rule status was (re)introduced.""" """In 2.28, the per access rule status was (re)introduced."""

View File

@ -1963,6 +1963,14 @@ class ShareActionsTest(test.TestCase):
access = self.controller.allow_access(req, share['id'], body) access = self.controller.allow_access(req, share['id'], body)
if api_version.APIVersionRequest(version) >= (
api_version.APIVersionRequest("2.33")):
expected_access.update(
{
'created_at': updated_access['created_at'],
'updated_at': updated_access['updated_at'],
})
self.assertEqual(expected_access, access['access']) self.assertEqual(expected_access, access['access'])
share_api.API.allow_access.assert_called_once_with( share_api.API.allow_access.assert_called_once_with(
req.environ['manila.context'], share, 'user', req.environ['manila.context'], share, 'user',

View File

@ -37,6 +37,8 @@ class ViewBuilderTestCase(test.TestCase):
'access_type': 'fakeaccesstype', 'access_type': 'fakeaccesstype',
'state': 'fakeaccessstate', 'state': 'fakeaccessstate',
'access_key': 'fakeaccesskey', 'access_key': 'fakeaccesskey',
'created_at': 'fakecreated_at',
'updated_at': 'fakeupdated_at',
} }
self.fake_share = { self.fake_share = {
'access_rules_status': self.fake_access['state'], 'access_rules_status': self.fake_access['state'],
@ -45,7 +47,7 @@ class ViewBuilderTestCase(test.TestCase):
def test_collection_name(self): def test_collection_name(self):
self.assertEqual('share_accesses', self.builder._collection_name) self.assertEqual('share_accesses', self.builder._collection_name)
@ddt.data("2.20", "2.21") @ddt.data("2.20", "2.21", "2.33")
def test_view(self, version): def test_view(self, version):
req = fakes.HTTPRequest.blank('/shares', version=version) req = fakes.HTTPRequest.blank('/shares', version=version)
self.mock_object(api.API, 'get', self.mock_object(api.API, 'get',
@ -57,9 +59,14 @@ class ViewBuilderTestCase(test.TestCase):
api_version.APIVersionRequest("2.21")): api_version.APIVersionRequest("2.21")):
del self.fake_access['access_key'] del self.fake_access['access_key']
if (api_version.APIVersionRequest(version) <
api_version.APIVersionRequest("2.33")):
del self.fake_access['created_at']
del self.fake_access['updated_at']
self.assertEqual({'access': self.fake_access}, result) self.assertEqual({'access': self.fake_access}, result)
@ddt.data("2.20", "2.21") @ddt.data("2.20", "2.21", "2.33")
def test_summary_view(self, version): def test_summary_view(self, version):
req = fakes.HTTPRequest.blank('/shares', version=version) req = fakes.HTTPRequest.blank('/shares', version=version)
self.mock_object(api.API, 'get', self.mock_object(api.API, 'get',
@ -70,11 +77,16 @@ class ViewBuilderTestCase(test.TestCase):
if (api_version.APIVersionRequest(version) < if (api_version.APIVersionRequest(version) <
api_version.APIVersionRequest("2.21")): api_version.APIVersionRequest("2.21")):
del self.fake_access['access_key'] del self.fake_access['access_key']
if (api_version.APIVersionRequest(version) <
api_version.APIVersionRequest("2.33")):
del self.fake_access['created_at']
del self.fake_access['updated_at']
del self.fake_access['share_id'] del self.fake_access['share_id']
self.assertEqual({'access': self.fake_access}, result) self.assertEqual({'access': self.fake_access}, result)
@ddt.data("2.20", "2.21") @ddt.data("2.20", "2.21", "2.33")
def test_list_view(self, version): def test_list_view(self, version):
req = fakes.HTTPRequest.blank('/shares', version=version) req = fakes.HTTPRequest.blank('/shares', version=version)
self.mock_object(api.API, 'get', self.mock_object(api.API, 'get',
@ -86,6 +98,11 @@ class ViewBuilderTestCase(test.TestCase):
if (api_version.APIVersionRequest(version) < if (api_version.APIVersionRequest(version) <
api_version.APIVersionRequest("2.21")): api_version.APIVersionRequest("2.21")):
del self.fake_access['access_key'] del self.fake_access['access_key']
if (api_version.APIVersionRequest(version) <
api_version.APIVersionRequest("2.33")):
del self.fake_access['created_at']
del self.fake_access['updated_at']
del self.fake_access['share_id'] del self.fake_access['share_id']
self.assertEqual({'access_list': accesses}, result) self.assertEqual({'access_list': accesses}, result)

View File

@ -30,7 +30,7 @@ ShareGroup = [
help="The minimum api microversion is configured to be the " help="The minimum api microversion is configured to be the "
"value of the minimum microversion supported by Manila."), "value of the minimum microversion supported by Manila."),
cfg.StrOpt("max_api_microversion", cfg.StrOpt("max_api_microversion",
default="2.32", default="2.33",
help="The maximum api microversion is configured to be the " help="The maximum api microversion is configured to be the "
"value of the latest microversion supported by Manila."), "value of the latest microversion supported by Manila."),
cfg.StrOpt("region", cfg.StrOpt("region",

View File

@ -494,6 +494,15 @@ class ShareRulesTest(base.BaseSharesTest):
rule = self.shares_v2_client.create_access_rule( rule = self.shares_v2_client.create_access_rule(
self.share["id"], self.access_type, self.access_to, self.share["id"], self.access_type, self.access_to,
version=version) version=version)
# verify added rule keys since 2.33 when create rule
if utils.is_microversion_ge(version, '2.33'):
self.assertIn('created_at', list(rule.keys()))
self.assertIn('updated_at', list(rule.keys()))
else:
self.assertNotIn('created_at', list(rule.keys()))
self.assertNotIn('updated_at', list(rule.keys()))
# rules must start out in 'new' until 2.28 & 'queued_to_apply' after # rules must start out in 'new' until 2.28 & 'queued_to_apply' after
if utils.is_microversion_le(version, "2.27"): if utils.is_microversion_le(version, "2.27"):
self.assertEqual("new", rule['state']) self.assertEqual("new", rule['state'])
@ -522,6 +531,8 @@ class ShareRulesTest(base.BaseSharesTest):
keys = ("id", "access_type", "access_to", "access_level") keys = ("id", "access_type", "access_to", "access_level")
if utils.is_microversion_ge(version, '2.21'): if utils.is_microversion_ge(version, '2.21'):
keys += ("access_key", ) keys += ("access_key", )
if utils.is_microversion_ge(version, '2.33'):
keys += ("created_at", "updated_at", )
for key in keys: for key in keys:
[self.assertIn(key, r.keys()) for r in rules] [self.assertIn(key, r.keys()) for r in rules]
for key in ('deleted', 'deleted_at', 'instance_mappings'): for key in ('deleted', 'deleted_at', 'instance_mappings'):

View File

@ -0,0 +1,5 @@
---
features:
- Beginning in API version 2.33, share access APIs return
"created_at" and "updated_at" for each access rule as part
of the JSON response.