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:
parent
713eaf1031
commit
a12ce4e0e4
@ -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:
|
||||
|
@ -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
25
glance/tests/functional/v2/test_metadef_tags.py
Normal file → Executable 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
35
glance/tests/unit/v2/test_metadef_resources.py
Normal file → Executable 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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user