Metadata definition namespaces api added
Test case added
This is to check the functionality of namespaces api:
creation of namespace, get the detail about created namespace,
verify that namespace in non-protective mode can only be deleted,
parameter updated for created namespace.
Change-Id: I9e0e434240ce2eeed3b3a3a511a5a1e8944371f5
diff --git a/tempest/api/image/v2/test_images_metadefs_namespaces.py b/tempest/api/image/v2/test_images_metadefs_namespaces.py
new file mode 100644
index 0000000..21247b1
--- /dev/null
+++ b/tempest/api/image/v2/test_images_metadefs_namespaces.py
@@ -0,0 +1,71 @@
+# Copyright 2015 Red Hat, Inc.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.image import base
+from tempest.common.utils import data_utils
+from tempest import test
+from tempest_lib import exceptions as lib_exc
+
+
+class MetadataNamespacesTest(base.BaseV2ImageTest):
+ """
+ Here we will test the Metadata definition Namespaces basic functionality.
+ """
+ @test.idempotent_id('319b765e-7f3d-4b3d-8b37-3ca3876ee768')
+ def test_basic_metadata_definition_namespaces(self):
+ # get the available resource types and use one resource_type
+ body = self.client.list_resource_types()
+ resource_name = body['resource_types'][0]['name']
+ name = [{'name': resource_name}]
+ namespace_name = data_utils.rand_name('namespace')
+ # create the metadef namespaces
+ body = self.client.create_namespaces(namespace=namespace_name,
+ visibility='public',
+ description='Tempest',
+ display_name=namespace_name,
+ resource_type_associations=name,
+ protected=True)
+ self.addCleanup(self._cleanup_namespace, namespace_name)
+ # get namespaces details
+ body = self.client.show_namespaces(namespace_name)
+ self.assertEqual(namespace_name, body['namespace'])
+ self.assertEqual('public', body['visibility'])
+ # unable to delete protected namespace
+ self.assertRaises(lib_exc.Forbidden, self.client.delete_namespaces,
+ namespace_name)
+ # update the visibility to private and protected to False
+ body = self.client.update_namespaces(namespace=namespace_name,
+ description='Tempest',
+ visibility='private',
+ display_name=namespace_name,
+ protected=False)
+ self.assertEqual('private', body['visibility'])
+ self.assertEqual(False, body['protected'])
+ # now able to delete the non-protected namespace
+ self.client.delete_namespaces(namespace_name)
+
+ def _cleanup_namespace(self, namespace_name):
+ # this is used to cleanup the resources
+ try:
+ body = self.client.show_namespaces(namespace_name)
+ self.assertEqual(namespace_name, body['namespace'])
+ body = self.client.update_namespaces(namespace=namespace_name,
+ description='Tempest',
+ visibility='private',
+ display_name=namespace_name,
+ protected=False)
+ self.client.delete_namespaces(namespace_name)
+ except lib_exc.NotFound:
+ pass
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 6cad746..eea179d 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -212,3 +212,63 @@
self.expected_success(200, resp.status)
body = json.loads(body)
return service_client.ResponseBody(resp, body)
+
+ def list_resource_types(self):
+ url = '/v2/metadefs/resource_types'
+ resp, body = self.get(url)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def create_namespaces(self, namespace, **kwargs):
+ params = {
+ "namespace": namespace,
+ }
+
+ for option in kwargs:
+ value = kwargs.get(option)
+ if isinstance(value, dict) or isinstance(value, tuple):
+ params.update(value)
+ else:
+ params[option] = value
+
+ data = json.dumps(params)
+ self._validate_schema(data)
+
+ resp, body = self.post('/v2/metadefs/namespaces', data)
+ self.expected_success(201, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def show_namespaces(self, namespace):
+ url = '/v2/metadefs/namespaces/%s' % namespace
+ resp, body = self.get(url)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def update_namespaces(self, namespace, visibility, **kwargs):
+ params = {
+ "namespace": namespace,
+ "visibility": visibility
+ }
+ for option in kwargs:
+ value = kwargs.get(option)
+ if isinstance(value, dict) or isinstance(value, tuple):
+ params.update(value)
+ else:
+ params[option] = value
+
+ data = json.dumps(params)
+ self._validate_schema(data)
+ url = '/v2/metadefs/namespaces/%s' % namespace
+ resp, body = self.put(url, body=data)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_namespaces(self, namespace):
+ url = '/v2/metadefs/namespaces/%s' % namespace
+ resp, _ = self.delete(url)
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp)