Fix re-adding deleted members to an image in v1
If you replace the membership list of an image with some members
that were previously deleted, we fail to re-add those deleted
members.
This seems to be a consequence of a previous commit
d6800e143d
which failed to update
the deleted records.
Closes-Bug: 1527143
Change-Id: Ic3ca9b56712a99652e65cb0a4e3f1e0ba15b8593
This commit is contained in:
parent
515203eac7
commit
700b7ef26d
|
@ -128,7 +128,8 @@ def _image_property_format(image_id, name, value):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _image_member_format(image_id, tenant_id, can_share, status='pending'):
|
def _image_member_format(image_id, tenant_id, can_share, status='pending',
|
||||||
|
deleted=False):
|
||||||
dt = timeutils.utcnow()
|
dt = timeutils.utcnow()
|
||||||
return {
|
return {
|
||||||
'id': str(uuid.uuid4()),
|
'id': str(uuid.uuid4()),
|
||||||
|
@ -138,6 +139,7 @@ def _image_member_format(image_id, tenant_id, can_share, status='pending'):
|
||||||
'status': status,
|
'status': status,
|
||||||
'created_at': dt,
|
'created_at': dt,
|
||||||
'updated_at': dt,
|
'updated_at': dt,
|
||||||
|
'deleted': deleted,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -503,7 +505,8 @@ def image_member_create(context, values):
|
||||||
member = _image_member_format(values['image_id'],
|
member = _image_member_format(values['image_id'],
|
||||||
values['member'],
|
values['member'],
|
||||||
values.get('can_share', False),
|
values.get('can_share', False),
|
||||||
values.get('status', 'pending'))
|
values.get('status', 'pending'),
|
||||||
|
values.get('deleted', False))
|
||||||
global DATA
|
global DATA
|
||||||
DATA['members'].append(member)
|
DATA['members'].append(member)
|
||||||
return copy.deepcopy(member)
|
return copy.deepcopy(member)
|
||||||
|
|
|
@ -1056,7 +1056,8 @@ def _image_member_format(member_ref):
|
||||||
'can_share': member_ref['can_share'],
|
'can_share': member_ref['can_share'],
|
||||||
'status': member_ref['status'],
|
'status': member_ref['status'],
|
||||||
'created_at': member_ref['created_at'],
|
'created_at': member_ref['created_at'],
|
||||||
'updated_at': member_ref['updated_at']
|
'updated_at': member_ref['updated_at'],
|
||||||
|
'deleted': member_ref['deleted']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,8 @@ class Controller(object):
|
||||||
# memberships to modify. Let's start by walking through all
|
# memberships to modify. Let's start by walking through all
|
||||||
# the existing image memberships...
|
# the existing image memberships...
|
||||||
existing_members = self.db_api.image_member_find(req.context,
|
existing_members = self.db_api.image_member_find(req.context,
|
||||||
image_id=image['id'])
|
image_id=image['id'],
|
||||||
|
include_deleted=True)
|
||||||
for member in existing_members:
|
for member in existing_members:
|
||||||
if member['id'] in existing:
|
if member['id'] in existing:
|
||||||
# Just update the membership in place
|
# Just update the membership in place
|
||||||
|
@ -185,6 +186,7 @@ class Controller(object):
|
||||||
member['id'],
|
member['id'],
|
||||||
update)
|
update)
|
||||||
else:
|
else:
|
||||||
|
if not member['deleted']:
|
||||||
# Outdated one; needs to be deleted
|
# Outdated one; needs to be deleted
|
||||||
self.db_api.image_member_delete(req.context, member['id'])
|
self.db_api.image_member_delete(req.context, member['id'])
|
||||||
|
|
||||||
|
|
|
@ -1173,6 +1173,7 @@ class DriverTests(object):
|
||||||
'image_id': UUID1,
|
'image_id': UUID1,
|
||||||
'can_share': False,
|
'can_share': False,
|
||||||
'status': 'pending',
|
'status': 'pending',
|
||||||
|
'deleted': False,
|
||||||
}
|
}
|
||||||
self.assertEqual(expected, actual)
|
self.assertEqual(expected, actual)
|
||||||
|
|
||||||
|
@ -1192,7 +1193,8 @@ class DriverTests(object):
|
||||||
expected = {'member': TENANT1,
|
expected = {'member': TENANT1,
|
||||||
'image_id': UUID1,
|
'image_id': UUID1,
|
||||||
'status': 'pending',
|
'status': 'pending',
|
||||||
'can_share': False}
|
'can_share': False,
|
||||||
|
'deleted': False}
|
||||||
self.assertEqual(expected, member)
|
self.assertEqual(expected, member)
|
||||||
|
|
||||||
member = self.db_api.image_member_update(self.context,
|
member = self.db_api.image_member_update(self.context,
|
||||||
|
@ -1206,7 +1208,8 @@ class DriverTests(object):
|
||||||
expected = {'member': TENANT1,
|
expected = {'member': TENANT1,
|
||||||
'image_id': UUID1,
|
'image_id': UUID1,
|
||||||
'status': 'pending',
|
'status': 'pending',
|
||||||
'can_share': True}
|
'can_share': True,
|
||||||
|
'deleted': False}
|
||||||
self.assertEqual(expected, member)
|
self.assertEqual(expected, member)
|
||||||
|
|
||||||
members = self.db_api.image_member_find(self.context,
|
members = self.db_api.image_member_find(self.context,
|
||||||
|
@ -1233,7 +1236,8 @@ class DriverTests(object):
|
||||||
expected = {'member': TENANT1,
|
expected = {'member': TENANT1,
|
||||||
'image_id': UUID1,
|
'image_id': UUID1,
|
||||||
'status': 'pending',
|
'status': 'pending',
|
||||||
'can_share': False}
|
'can_share': False,
|
||||||
|
'deleted': False}
|
||||||
self.assertEqual(expected, member)
|
self.assertEqual(expected, member)
|
||||||
|
|
||||||
member = self.db_api.image_member_update(self.context,
|
member = self.db_api.image_member_update(self.context,
|
||||||
|
@ -1247,7 +1251,8 @@ class DriverTests(object):
|
||||||
expected = {'member': TENANT1,
|
expected = {'member': TENANT1,
|
||||||
'image_id': UUID1,
|
'image_id': UUID1,
|
||||||
'status': 'accepted',
|
'status': 'accepted',
|
||||||
'can_share': False}
|
'can_share': False,
|
||||||
|
'deleted': False}
|
||||||
self.assertEqual(expected, member)
|
self.assertEqual(expected, member)
|
||||||
|
|
||||||
members = self.db_api.image_member_find(self.context,
|
members = self.db_api.image_member_find(self.context,
|
||||||
|
|
|
@ -1640,6 +1640,34 @@ class TestRegistryAPI(base.IsolatedUnitTest, test_utils.RegistryAPIMixIn):
|
||||||
method='PUT', body=body,
|
method='PUT', body=body,
|
||||||
content_type='json')
|
content_type='json')
|
||||||
|
|
||||||
|
def test_update_all_image_existing_deleted_members(self):
|
||||||
|
"""
|
||||||
|
Test update existing image members
|
||||||
|
"""
|
||||||
|
UUID8 = _gen_uuid()
|
||||||
|
extra_fixture = self.get_fixture(id=UUID8, size=19, protected=False,
|
||||||
|
owner='test user')
|
||||||
|
|
||||||
|
db_api.image_create(self.context, extra_fixture)
|
||||||
|
|
||||||
|
# Add a new member to an image
|
||||||
|
req = webob.Request.blank('/images/%s/members/test1' % UUID8)
|
||||||
|
req.method = 'PUT'
|
||||||
|
req.get_response(self.api)
|
||||||
|
|
||||||
|
# Delete the existing member
|
||||||
|
self.get_api_response_ext(204, method='DELETE',
|
||||||
|
url='/images/%s/members/test1' % UUID8)
|
||||||
|
|
||||||
|
# Re-add the deleted member by replacing membership list
|
||||||
|
fixture = [dict(member_id='test1', can_share=False)]
|
||||||
|
body = jsonutils.dump_as_bytes(dict(memberships=fixture))
|
||||||
|
self.get_api_response_ext(204, url='/images/%s/members' % UUID8,
|
||||||
|
method='PUT', body=body,
|
||||||
|
content_type='json')
|
||||||
|
memb_list = db_api.image_member_find(self.context, image_id=UUID8)
|
||||||
|
self.assertEqual(1, len(memb_list))
|
||||||
|
|
||||||
def test_add_member(self):
|
def test_add_member(self):
|
||||||
"""
|
"""
|
||||||
Tests adding image members raises right exception
|
Tests adding image members raises right exception
|
||||||
|
|
Loading…
Reference in New Issue