Added better schemas for image members, revised tests.
Related to bp glance-api-v2-image-sharing Change-Id: I01c7fdb78177aaee97f6e7836dea3326b57be33c
This commit is contained in:
parent
4b705d7ee7
commit
a2a4bdd060
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import json
|
||||
import webob
|
||||
|
||||
@ -25,6 +26,7 @@ import glance.domain
|
||||
import glance.gateway
|
||||
import glance.notifier
|
||||
from glance.openstack.common import timeutils
|
||||
import glance.schema
|
||||
import glance.store
|
||||
|
||||
|
||||
@ -50,6 +52,7 @@ class ImageMembersController(object):
|
||||
|
||||
{'member_id': <MEMBER>,
|
||||
'image_id': <IMAGE>,
|
||||
'status': <MEMBER_STATUS>
|
||||
'created_at': ..,
|
||||
'updated_at': ..}
|
||||
|
||||
@ -82,6 +85,7 @@ class ImageMembersController(object):
|
||||
|
||||
{'member_id': <MEMBER>,
|
||||
'image_id': <IMAGE>,
|
||||
'status': <MEMBER_STATUS>
|
||||
'created_at': ..,
|
||||
'updated_at': ..}
|
||||
|
||||
@ -115,6 +119,7 @@ class ImageMembersController(object):
|
||||
{'members': [
|
||||
{'member_id': <MEMBER>,
|
||||
'image_id': <IMAGE>,
|
||||
'status': <MEMBER_STATUS>
|
||||
'created_at': ..,
|
||||
'updated_at': ..}, ..
|
||||
]}
|
||||
@ -207,6 +212,7 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
|
||||
class ResponseSerializer(wsgi.JSONResponseSerializer):
|
||||
def __init__(self, schema=None):
|
||||
super(ResponseSerializer, self).__init__()
|
||||
self.schema = schema or get_schema()
|
||||
|
||||
def _format_image_member(self, member):
|
||||
member_view = {}
|
||||
@ -215,6 +221,8 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
|
||||
member_view[key] = getattr(member, key)
|
||||
member_view['created_at'] = timeutils.isotime(member.created_at)
|
||||
member_view['updated_at'] = timeutils.isotime(member.updated_at)
|
||||
member_view['schema'] = '/v2/schemas/member'
|
||||
member_view = self.schema.filter(member_view)
|
||||
return member_view
|
||||
|
||||
def create(self, response, image_member):
|
||||
@ -235,11 +243,60 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
|
||||
for image_member in image_members:
|
||||
image_member_view = self._format_image_member(image_member)
|
||||
image_members_view.append(image_member_view)
|
||||
body = json.dumps(dict(members=image_members_view), ensure_ascii=False)
|
||||
totalview = dict(members=image_members_view)
|
||||
totalview['schema'] = '/v2/schemas/members'
|
||||
body = json.dumps(totalview, ensure_ascii=False)
|
||||
response.unicode_body = unicode(body)
|
||||
response.content_type = 'application/json'
|
||||
|
||||
|
||||
_MEMBER_SCHEMA = {
|
||||
'member_id': {
|
||||
'type': 'string',
|
||||
'description': _('An identifier for the image member (tenantId)')
|
||||
},
|
||||
'image_id': {
|
||||
'type': 'string',
|
||||
'description': _('An identifier for the image'),
|
||||
'pattern': ('^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}'
|
||||
'-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$'),
|
||||
},
|
||||
'created_at': {
|
||||
'type': 'string',
|
||||
'description': _('Date and time of image member creation'),
|
||||
#TODO(brian-rosmaita): our jsonschema library doesn't seem to like the
|
||||
# format attribute, figure out why (and also fix in images.py)
|
||||
#'format': 'date-time',
|
||||
},
|
||||
'updated_at': {
|
||||
'type': 'string',
|
||||
'description': _('Date and time of last modification of image member'),
|
||||
#'format': 'date-time',
|
||||
},
|
||||
'status': {
|
||||
'type': 'string',
|
||||
'description': _('The status of this image member'),
|
||||
'enum': [
|
||||
'pending',
|
||||
'accepted',
|
||||
'rejected'
|
||||
]
|
||||
},
|
||||
'schema': {'type': 'string'}
|
||||
}
|
||||
|
||||
|
||||
def get_schema():
|
||||
properties = copy.deepcopy(_MEMBER_SCHEMA)
|
||||
schema = glance.schema.Schema('member', properties)
|
||||
return schema
|
||||
|
||||
|
||||
def get_collection_schema():
|
||||
member_schema = get_schema()
|
||||
return glance.schema.CollectionSchema('members', member_schema)
|
||||
|
||||
|
||||
def create_resource():
|
||||
"""Image Members resource factory method"""
|
||||
deserializer = RequestDeserializer()
|
||||
|
@ -39,6 +39,14 @@ class API(wsgi.Router):
|
||||
controller=schemas_resource,
|
||||
action='images',
|
||||
conditions={'method': ['GET']})
|
||||
mapper.connect('/schemas/member',
|
||||
controller=schemas_resource,
|
||||
action='member',
|
||||
conditions={'method': ['GET']})
|
||||
mapper.connect('/schemas/members',
|
||||
controller=schemas_resource,
|
||||
action='members',
|
||||
conditions={'method': ['GET']})
|
||||
|
||||
images_resource = images.create_resource(custom_image_properties)
|
||||
mapper.connect('/images',
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
from glance.api.v2 import images
|
||||
from glance.api.v2 import image_members
|
||||
from glance.common import wsgi
|
||||
|
||||
|
||||
@ -22,6 +23,8 @@ class Controller(object):
|
||||
self.image_schema = images.get_schema(custom_image_properties)
|
||||
self.image_collection_schema = images.get_collection_schema(
|
||||
custom_image_properties)
|
||||
self.member_schema = image_members.get_schema()
|
||||
self.member_collection_schema = image_members.get_collection_schema()
|
||||
|
||||
def image(self, req):
|
||||
return self.image_schema.raw()
|
||||
@ -29,6 +32,12 @@ class Controller(object):
|
||||
def images(self, req):
|
||||
return self.image_collection_schema.raw()
|
||||
|
||||
def member(self, req):
|
||||
return self.member_schema.minimal()
|
||||
|
||||
def members(self, req):
|
||||
return self.member_collection_schema.minimal()
|
||||
|
||||
|
||||
def create_resource(custom_image_properties=None):
|
||||
controller = Controller(custom_image_properties)
|
||||
|
@ -69,6 +69,13 @@ class Schema(object):
|
||||
raw['links'] = self.links
|
||||
return raw
|
||||
|
||||
def minimal(self):
|
||||
minimal = {
|
||||
'name': self.name,
|
||||
'properties': self.properties
|
||||
}
|
||||
return minimal
|
||||
|
||||
|
||||
class PermissiveSchema(Schema):
|
||||
@staticmethod
|
||||
@ -80,6 +87,10 @@ class PermissiveSchema(Schema):
|
||||
raw['additionalProperties'] = {'type': 'string'}
|
||||
return raw
|
||||
|
||||
def minimal(self):
|
||||
minimal = super(PermissiveSchema, self).raw()
|
||||
return minimal
|
||||
|
||||
|
||||
class CollectionSchema(object):
|
||||
|
||||
@ -105,3 +116,18 @@ class CollectionSchema(object):
|
||||
{'rel': 'describedby', 'href': '{schema}'},
|
||||
],
|
||||
}
|
||||
|
||||
def minimal(self):
|
||||
return {
|
||||
'name': self.name,
|
||||
'properties': {
|
||||
self.name: {
|
||||
'type': 'array',
|
||||
'items': self.item_schema.minimal(),
|
||||
},
|
||||
'schema': {'type': 'string'},
|
||||
},
|
||||
'links': [
|
||||
{'rel': 'describedby', 'href': '{schema}'},
|
||||
],
|
||||
}
|
||||
|
@ -294,6 +294,7 @@ class TestImageMembersSerializer(test_utils.BaseTestCase):
|
||||
'status': 'accepted',
|
||||
'created_at': ISOTIME,
|
||||
'updated_at': ISOTIME,
|
||||
'schema': '/v2/schemas/member',
|
||||
},
|
||||
{
|
||||
'image_id': UUID2,
|
||||
@ -301,8 +302,10 @@ class TestImageMembersSerializer(test_utils.BaseTestCase):
|
||||
'status': 'pending',
|
||||
'created_at': ISOTIME,
|
||||
'updated_at': ISOTIME,
|
||||
'schema': '/v2/schemas/member',
|
||||
},
|
||||
]
|
||||
],
|
||||
'schema': '/v2/schemas/members',
|
||||
}
|
||||
request = webob.Request.blank('/v2/images/%s/members' % UUID2)
|
||||
response = webob.Response(request=request)
|
||||
@ -316,6 +319,7 @@ class TestImageMembersSerializer(test_utils.BaseTestCase):
|
||||
expected = {'image_id': UUID2,
|
||||
'member_id': TENANT1,
|
||||
'status': 'accepted',
|
||||
'schema': '/v2/schemas/member',
|
||||
'created_at': ISOTIME,
|
||||
'updated_at': ISOTIME}
|
||||
request = webob.Request.blank('/v2/images/%s/members/%s'
|
||||
@ -331,6 +335,7 @@ class TestImageMembersSerializer(test_utils.BaseTestCase):
|
||||
expected = {'image_id': UUID2,
|
||||
'member_id': TENANT1,
|
||||
'status': 'accepted',
|
||||
'schema': '/v2/schemas/member',
|
||||
'created_at': ISOTIME,
|
||||
'updated_at': ISOTIME}
|
||||
request = webob.Request.blank('/v2/images/%s/members/%s'
|
||||
|
Loading…
Reference in New Issue
Block a user