Fix wrong uuid recognized when create group

We can't create a group with a uuid format name volume type,
there is a uuid check in "volume_types_get_by_name_or_id()",
and the uuid-like type name would be mistakenly recognized as
a id, finally, it will use "get_volume_type"(by_id) to get
volume type and cause a 404 error.

So, this patch try to fix this error, if we can't find a
type by uuid, we need call "_volume_type_get_by_name" to check
again can we get this type by name.

Change-Id: Id09230bffc0ad83093bb6254b2e09aca5d1c58b1
Closes-bug: #1794716
Related-bug: #1794237
This commit is contained in:
Yikun Jiang 2018-09-27 19:08:25 +08:00
parent 6f1648e399
commit 0b8b3a4b47
3 changed files with 60 additions and 2 deletions

View File

@ -4013,7 +4013,14 @@ def volume_types_get_by_name_or_id(context, volume_type_list):
if not uuidutils.is_uuid_like(vol_t):
vol_type = _volume_type_get_by_name(context, vol_t)
else:
vol_type = _volume_type_get(context, vol_t)
try:
vol_type = _volume_type_get(context, vol_t)
except exception.VolumeTypeNotFound:
# check again if we get this volume type by uuid-like name
try:
vol_type = _volume_type_get_by_name(context, vol_t)
except exception.VolumeTypeNotFoundByName:
raise exception.VolumeTypeNotFound(volume_type_id=vol_t)
req_volume_types.append(vol_type)
return req_volume_types

View File

@ -110,7 +110,15 @@ class API(base.Base):
req_group_type = self.db.group_type_get_by_name(context,
group_type)
else:
req_group_type = self.db.group_type_get(context, group_type)
try:
req_group_type = self.db.group_type_get(context, group_type)
except exception.GroupTypeNotFound:
# check again if we get this group type by uuid-like name
try:
req_group_type = self.db.group_type_get_by_name(
context, group_type)
except exception.GroupTypeNotFoundByName:
raise exception.GroupTypeNotFound(group_type_id=group_type)
availability_zone = self._extract_availability_zone(availability_zone)
kwargs = {'user_id': context.user_id,

View File

@ -142,6 +142,49 @@ class GroupAPITestCase(test.TestCase):
mock_group_type_get.assert_called_once_with(self.ctxt,
"fake-grouptype-name")
@mock.patch('cinder.group.api.API._cast_create_group')
@mock.patch('cinder.group.api.API.update_quota')
@mock.patch('cinder.db.group_type_get')
@mock.patch('cinder.db.group_type_get_by_name')
@mock.patch('cinder.db.volume_types_get_by_name_or_id')
def test_create_with_uuid_format_group_type_name(
self, mock_volume_types_get, mock_group_type_get_by_name,
mock_group_type_get, mock_update_quota, mock_cast_create_group):
uuid_format_type_name = fake.UUID1
mock_volume_types_get.return_value = [{'id': fake.VOLUME_TYPE_ID}]
mock_group_type_get.side_effect = exception.GroupTypeNotFound(
group_type_id=uuid_format_type_name)
mock_group_type_get_by_name.return_value = {'id': fake.GROUP_TYPE_ID}
ret_group = self.group_api.create(self.ctxt, "test_group", '',
uuid_format_type_name,
[fake.VOLUME_TYPE_ID],
availability_zone='nova')
self.assertEqual(ret_group["group_type_id"],
fake.GROUP_TYPE_ID)
@mock.patch('cinder.group.api.API._cast_create_group')
@mock.patch('cinder.group.api.API.update_quota')
@mock.patch('cinder.db.group_type_get_by_name')
@mock.patch('cinder.db.sqlalchemy.api._volume_type_get')
@mock.patch('cinder.db.sqlalchemy.api._volume_type_get_by_name')
def test_create_with_uuid_format_volume_type_name(
self, mock_vol_t_get_by_name, mock_vol_types_get_by_id,
mock_group_type_get, mock_update_quota, mock_cast_create_group):
uuid_format_name = fake.UUID1
mock_group_type_get.return_value = {'id': fake.GROUP_TYPE_ID}
volume_type = {'id': fake.VOLUME_TYPE_ID, 'name': uuid_format_name}
mock_vol_types_get_by_id.side_effect = exception.VolumeTypeNotFound(
volume_type_id=uuid_format_name)
mock_vol_t_get_by_name.return_value = volume_type
group = self.group_api.create(self.ctxt, "test_group",
"this is a test group",
"fake-grouptype-name",
[uuid_format_name],
availability_zone='nova')
self.assertEqual(group["volume_type_ids"],
[volume_type['id']])
@mock.patch('cinder.group.api.API._cast_create_group')
@mock.patch('cinder.group.api.API.update_quota')
@mock.patch('cinder.db.group_type_get_by_name')