The metadef tags create api does not match blue-print

The blueprint for metadef tags shows:
Create / Replace all tags in a specific namespace
    POST /metadefs/namespaces/{namespace}/tags/
and
Add tag in a specific namespace:
    POST /metadefs/namespaces/{namespace}/tags/{tag}

Unfortunately, these were implemented as:
Create / Replace all tags in a specific namespace
    PUT /metadefs/namespaces/{namespace}/tags/
and
    POST /metadefs/namespaces/{namespace}/tags/

This bug seeks to rectify this situation and use the correct
action/URI. Even though the metadef tag library has been checked in,
the associated python-glanceclient check in has not been approved yet.
Additionally, the specs for the metadef tag changes have not been posted
anywhere, so, hopefully this can be changed with minimal impact.

Change-Id: I7d46c529e50b69a386ad7162c65187cec4b66249
Closes-Bug: 1419945
This commit is contained in:
Wayne Okuma 2015-02-09 12:37:17 -08:00
parent 713eaf1031
commit a12ce4e0e4
4 changed files with 30 additions and 61 deletions

View File

@ -48,13 +48,14 @@ class TagsController(object):
policy_enforcer=self.policy)
self.tag_schema_link = '/v2/schemas/metadefs/tag'
def create(self, req, metadata_tag, namespace):
def create(self, req, namespace, tag_name):
tag_factory = self.gateway.get_metadef_tag_factory(req.context)
tag_repo = self.gateway.get_metadef_tag_repo(req.context)
tag_name_as_dict = {'name': tag_name}
try:
new_meta_tag = tag_factory.new_tag(
namespace=namespace,
**metadata_tag.to_dict())
**tag_name_as_dict)
tag_repo.add(new_meta_tag)
except exception.Forbidden as e:
raise webob.exc.HTTPForbidden(explanation=e.msg)
@ -286,7 +287,7 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
return limit
def _create_or_update(self, request):
def update(self, request):
body = self._get_request_body(request)
self._check_allowed(body)
try:
@ -316,9 +317,6 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
return query_params
def create(self, request):
return self._create_or_update(request)
def create_tags(self, request):
body = self._get_request_body(request)
self._check_allowed(body)
@ -329,9 +327,6 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
metadata_tags = json.fromjson(MetadefTags, body)
return dict(metadata_tags=metadata_tags)
def update(self, request):
return self._create_or_update(request)
@classmethod
def _check_allowed(cls, image):
for key in cls._disallowed_properties:

View File

@ -377,14 +377,10 @@ class API(wsgi.Router):
controller=metadef_tags_resource,
action='index',
conditions={'method': ['GET']})
mapper.connect('/metadefs/namespaces/{namespace}/tags',
controller=metadef_tags_resource,
action='create',
conditions={'method': ['POST']})
mapper.connect('/metadefs/namespaces/{namespace}/tags',
controller=metadef_tags_resource,
action='create_tags',
conditions={'method': ['PUT']})
conditions={'method': ['POST']})
mapper.connect('/metadefs/namespaces/{namespace}/tags',
controller=metadef_namespace_resource,
action='delete_tags',
@ -392,13 +388,17 @@ class API(wsgi.Router):
mapper.connect('/metadefs/namespaces/{namespace}/tags',
controller=reject_method_resource,
action='reject',
allowed_methods='GET, POST, PUT, DELETE',
conditions={'method': ['PATCH', 'HEAD']})
allowed_methods='GET, POST, DELETE',
conditions={'method': ['PUT', 'PATCH', 'HEAD']})
mapper.connect('/metadefs/namespaces/{namespace}/tags/{tag_name}',
controller=metadef_tags_resource,
action='show',
conditions={'method': ['GET']})
mapper.connect('/metadefs/namespaces/{namespace}/tags/{tag_name}',
controller=metadef_tags_resource,
action='create',
conditions={'method': ['POST']})
mapper.connect('/metadefs/namespaces/{namespace}/tags/{tag_name}',
controller=metadef_tags_resource,
action='update',
@ -410,8 +410,8 @@ class API(wsgi.Router):
mapper.connect('/metadefs/namespaces/{namespace}/tags/{tag_name}',
controller=reject_method_resource,
action='reject',
allowed_methods='GET, PUT, DELETE',
conditions={'method': ['POST', 'PATCH', 'HEAD']})
allowed_methods='GET, POST, PUT, DELETE',
conditions={'method': ['PATCH', 'HEAD']})
images_resource = images.create_resource(custom_image_properties)
mapper.connect('/images',

25
glance/tests/functional/v2/test_metadef_tags.py Normal file → Executable file
View File

@ -66,31 +66,24 @@ class TestMetadefTags(functional.FunctionalTest):
response = requests.post(path, headers=headers, data=data)
self.assertEqual(201, response.status_code)
# Metadata tags should not exist
path = self._url('/v2/metadefs/namespaces/MyNamespace/tags/tag1')
# Metadata tag should not exist
metadata_tag_name = "tag1"
path = self._url('/v2/metadefs/namespaces/%s/tags/%s' %
(namespace_name, metadata_tag_name))
response = requests.get(path, headers=self._headers())
self.assertEqual(404, response.status_code)
# Create a tag
path = self._url('/v2/metadefs/namespaces/MyNamespace/tags')
# Create the metadata tag
headers = self._headers({'content-type': 'application/json'})
metadata_tag_name = "tag1"
data = jsonutils.dumps(
{
"name": metadata_tag_name
}
)
response = requests.post(path, headers=headers, data=data)
response = requests.post(path, headers=headers)
self.assertEqual(201, response.status_code)
# Get the metadata tag created above
path = self._url('/v2/metadefs/namespaces/%s/tags/%s' %
(namespace_name, metadata_tag_name))
response = requests.get(path,
headers=self._headers())
self.assertEqual(200, response.status_code)
metadata_tag = jsonutils.loads(response.text)
self.assertEqual("tag1", metadata_tag['name'])
self.assertEqual(metadata_tag_name, metadata_tag['name'])
# Returned tag should match the created tag
metadata_tag = jsonutils.loads(response.text)
@ -156,7 +149,7 @@ class TestMetadefTags(functional.FunctionalTest):
data = jsonutils.dumps(
{"tags": [{"name": "tag1"}, {"name": "tag2"}, {"name": "tag3"}]}
)
response = requests.put(path, headers=headers, data=data)
response = requests.post(path, headers=headers, data=data)
self.assertEqual(201, response.status_code)
# List out the three new tags.
@ -169,7 +162,7 @@ class TestMetadefTags(functional.FunctionalTest):
data = jsonutils.dumps(
{"tags": [{"name": "tag4"}, {"name": "tag5"}, {"name": "tag4"}]}
)
response = requests.put(path, headers=headers, data=data)
response = requests.post(path, headers=headers, data=data)
self.assertEqual(409, response.status_code)
# Verify the previous 3 still exist

35
glance/tests/unit/v2/test_metadef_resources.py Normal file → Executable file
View File

@ -1267,10 +1267,7 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
def test_tag_create(self):
request = unit_test_utils.get_fake_request()
tag = glance.api.v2.model.metadef_tag.MetadefTag()
tag.name = TAG2
tag = self.tag_controller.create(request, tag, NAMESPACE1)
tag = self.tag_controller.create(request, NAMESPACE1, TAG2)
self.assertEqual(TAG2, tag.name)
tag = self.tag_controller.show(request, NAMESPACE1, TAG2)
@ -1328,42 +1325,26 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
def test_tag_create_conflict(self):
request = unit_test_utils.get_fake_request()
tag = glance.api.v2.model.metadef_tag.MetadefTag()
tag.name = TAG1
self.assertRaises(webob.exc.HTTPConflict,
self.tag_controller.create, request, tag,
NAMESPACE1)
self.tag_controller.create, request,
NAMESPACE1, TAG1)
def test_tag_create_non_existing_namespace(self):
request = unit_test_utils.get_fake_request()
tag = glance.api.v2.model.metadef_tag.MetadefTag()
tag.name = TAG1
self.assertRaises(webob.exc.HTTPNotFound,
self.tag_controller.create, request, tag,
NAMESPACE4)
self.tag_controller.create, request,
NAMESPACE4, TAG1)
def test_tag_create_non_visible_namespace(self):
request = unit_test_utils.get_fake_request(tenant=TENANT2)
tag = glance.api.v2.model.metadef_tag.MetadefTag()
tag.name = TAG1
self.assertRaises(webob.exc.HTTPForbidden,
self.tag_controller.create, request, tag,
NAMESPACE1)
self.tag_controller.create, request,
NAMESPACE1, TAG1)
def test_tag_create_non_visible_namespace_admin(self):
request = unit_test_utils.get_fake_request(tenant=TENANT2,
is_admin=True)
tag = glance.api.v2.model.metadef_tag.MetadefTag()
tag.name = TAG2
tag = self.tag_controller.create(request, tag, NAMESPACE1)
tag = self.tag_controller.create(request, NAMESPACE1, TAG2)
self.assertEqual(TAG2, tag.name)
tag = self.tag_controller.show(request, NAMESPACE1, TAG2)