Refactor rbac metadef tests structure
Change-Id: I5b1c552b8de2f29be1cd065d4a35ff706993de5c
This commit is contained in:
@@ -17,6 +17,7 @@ from tempest import config
|
||||
from tempest.lib import auth
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib.common.utils import test_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
@@ -258,3 +259,432 @@ class ImageV2RbacTemplate(metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def test_reactivate_image(self):
|
||||
pass
|
||||
|
||||
|
||||
class MetadefV2RbacNamespaceTest(RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacNamespaceTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespaces_client.project_id
|
||||
cls.alt_project_id = cls.alt_persona.namespaces_client.project_id
|
||||
cls.admin_namespace_client = cls.os_project_admin.namespaces_client
|
||||
cls.namespace_client = cls.persona.namespaces_client
|
||||
cls.alt_namespace_client = cls.alt_persona.namespaces_client
|
||||
|
||||
def assertListNamespaces(self, actual, expected, owner=None):
|
||||
expected_ns = set(ns['namespace'] for ns in expected['namespaces'])
|
||||
if owner:
|
||||
for ns in actual:
|
||||
if (ns['visibility'] == 'private' and
|
||||
ns['owner'] != owner):
|
||||
self.assertNotIn(ns['namespace'], expected_ns)
|
||||
else:
|
||||
self.assertIn(ns['namespace'], expected_ns)
|
||||
else:
|
||||
for ns in actual:
|
||||
self.assertIn(ns['namespace'], expected_ns)
|
||||
|
||||
|
||||
class MetadefV2RbacNamespaceTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_namespace(self):
|
||||
"""Test get_metadef_namespace policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_namespaces(self):
|
||||
"""Test get_metadef_namespaces policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_update_namespace(self):
|
||||
"""Test modify_metadef_namespace policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_namespace(self):
|
||||
"""Test add_metadef_namespace policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_namespace(self):
|
||||
"""Test delete_metadef_namespace policy."""
|
||||
pass
|
||||
|
||||
|
||||
class MetadefV2RbacResourceTypeTest(RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacResourceTypeTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespaces_client.project_id
|
||||
cls.alt_project_id = cls.alt_persona.namespaces_client.project_id
|
||||
cls.resource_types_client = cls.persona.resource_types_client
|
||||
|
||||
def create_resource_types(self):
|
||||
# Create namespace for two different projects
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
namespace_resource_types = []
|
||||
for ns in namespaces:
|
||||
alt_client = None
|
||||
if ns['namespace'].startswith(self.alt_project_id):
|
||||
alt_client = self.os_project_alt_admin.resource_types_client
|
||||
client = alt_client
|
||||
if alt_client is None:
|
||||
client = self.os_project_admin.resource_types_client
|
||||
resource_name = "rs_type_of_%s" % (ns['namespace'])
|
||||
resource_type = client.create_resource_type_association(
|
||||
ns['namespace'], name=resource_name)
|
||||
resource_types = {'namespace': ns,
|
||||
'resource_type': resource_type}
|
||||
namespace_resource_types.append(resource_types)
|
||||
|
||||
return namespace_resource_types
|
||||
|
||||
def assertRSTypeList(self, ns_rs_types, resp):
|
||||
actual_rs_types = set(rt['name'] for rt in resp['resource_types'])
|
||||
|
||||
for rs_type in ns_rs_types:
|
||||
self.assertIn(rs_type['resource_type']['name'],
|
||||
actual_rs_types)
|
||||
|
||||
|
||||
class MetadefV2RbacResourceTypeTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_resource_type(self):
|
||||
"""Test add_metadef_resource_type_association policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_resource_type(self):
|
||||
"""Test get_metadef_resource_type policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_resource_types(self):
|
||||
"""Test list_metadef_resource_types policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_resource_type(self):
|
||||
"""Test remove_metadef_resource_type_association policy."""
|
||||
pass
|
||||
|
||||
|
||||
class MetadefV2RbacObjectsTest(RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacObjectsTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespace_objects_client.project_id
|
||||
cls.alt_project_id = \
|
||||
cls.alt_persona.namespace_objects_client.project_id
|
||||
cls.objects_client = cls.persona.namespace_objects_client
|
||||
|
||||
def create_objects(self):
|
||||
# Create namespace for two different projects
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
client = self.os_project_admin.namespace_objects_client
|
||||
namespace_objects = []
|
||||
for ns in namespaces:
|
||||
if ns['namespace'].startswith(self.project_id):
|
||||
client = self.os_project_alt_admin.namespace_objects_client
|
||||
object_name = "object_of_%s" % (ns['namespace'])
|
||||
namespace_object = client.create_namespace_object(
|
||||
ns['namespace'], name=object_name,
|
||||
description=data_utils.arbitrary_string())
|
||||
|
||||
obj = {'namespace': ns, 'object': namespace_object}
|
||||
namespace_objects.append(obj)
|
||||
|
||||
return namespace_objects
|
||||
|
||||
def assertObjectsList(self, actual_obj, client, owner=None):
|
||||
ns = actual_obj['namespace']
|
||||
if owner:
|
||||
if not (ns['visibility'] == 'public' or
|
||||
ns['owner'] == owner):
|
||||
self.do_request('list_namespace_objects',
|
||||
expected_status=exceptions.NotFound,
|
||||
namespace=ns['namespace'],
|
||||
client=client)
|
||||
else:
|
||||
resp = self.do_request('list_namespace_objects',
|
||||
expected_status=200,
|
||||
namespace=ns['namespace'],
|
||||
client=client)
|
||||
self.assertIn(actual_obj['object']['name'],
|
||||
resp['objects'][0]['name'])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_objects',
|
||||
expected_status=200,
|
||||
namespace=ns['namespace'],
|
||||
client=client)
|
||||
self.assertIn(actual_obj['object']['name'],
|
||||
resp['objects'][0]['name'])
|
||||
|
||||
|
||||
class MetadefV2RbacObjectsTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_object(self):
|
||||
"""Test add_metadef_object policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_object(self):
|
||||
"""Test get_metadef_object policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_objects(self):
|
||||
"""Test list_metadef_objects policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_update_object(self):
|
||||
"""Test update_metadef_object policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_object(self):
|
||||
"""Test delete_metadef_object policy."""
|
||||
pass
|
||||
|
||||
|
||||
class MetadefV2RbacPropertiesTest(RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacPropertiesTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespaces_client.project_id
|
||||
cls.alt_project_id = cls.alt_persona.namespaces_client.project_id
|
||||
cls.properties_client = cls.persona.namespace_properties_client
|
||||
|
||||
def create_properties(self):
|
||||
# Create namespace for two different projects
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
namespace_properties = []
|
||||
for ns in namespaces:
|
||||
alt_client = None
|
||||
if ns['namespace'].startswith(self.alt_project_id):
|
||||
alt_client = \
|
||||
self.os_project_alt_admin.namespace_properties_client
|
||||
client = alt_client
|
||||
if alt_client is None:
|
||||
client = self.os_project_admin.namespace_properties_client
|
||||
|
||||
property_name = "prop_of_%s" % (ns['namespace'])
|
||||
namespace_property = client.create_namespace_property(
|
||||
ns['namespace'], name=property_name, title='property',
|
||||
type='integer')
|
||||
|
||||
prop = {'namespace': ns, 'property': namespace_property}
|
||||
namespace_properties.append(prop)
|
||||
|
||||
return namespace_properties
|
||||
|
||||
def assertPropertyList(self, actual_prop, client, owner=None):
|
||||
ns = actual_prop['namespace']
|
||||
if owner:
|
||||
if not (ns['visibility'] == 'public' or ns['owner'] == owner):
|
||||
resp = self.do_request('list_namespace_properties',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_properties',
|
||||
expected_status=200,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
self.assertEqual(actual_prop['property']['name'],
|
||||
[*resp['properties']][0])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_properties',
|
||||
expected_status=200,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
self.assertEqual(actual_prop['property']['name'],
|
||||
[*resp['properties']][0])
|
||||
|
||||
|
||||
class MetadefV2RbacPropertiesTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_property(self):
|
||||
"""Test add_metadef_property policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_properties(self):
|
||||
"""Test get_metadef_property policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_properties(self):
|
||||
"""Test list_metadef_properties policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_update_properties(self):
|
||||
"""Test update_metadef_property policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_properties(self):
|
||||
"""Test delete_metadef_property policy."""
|
||||
pass
|
||||
|
||||
|
||||
class MetadefV2RbacTagsTest(RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacTagsTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespaces_client.project_id
|
||||
cls.alt_project_id = cls.alt_persona.namespaces_client.project_id
|
||||
cls.tags_client = cls.persona.namespace_tags_client
|
||||
|
||||
def create_tags(self, namespaces, multiple_tags=False):
|
||||
namespace_tags = []
|
||||
|
||||
if multiple_tags:
|
||||
tags = [{"name": "tag1"}, {"name": "tag2"}, {"name": "tag3"}]
|
||||
for ns in namespaces:
|
||||
alt_client = None
|
||||
if ns['namespace'].startswith(self.alt_project_id):
|
||||
alt_client = \
|
||||
self.os_project_alt_admin.namespace_tags_client
|
||||
client = alt_client
|
||||
if alt_client is None:
|
||||
client = self.os_project_admin.namespace_tags_client
|
||||
multiple_tags = client.create_namespace_tags(
|
||||
ns['namespace'], tags=tags)
|
||||
|
||||
namespace_multiple_tags = {'namespace': ns,
|
||||
'tags': multiple_tags}
|
||||
namespace_tags.append(namespace_multiple_tags)
|
||||
else:
|
||||
for ns in namespaces:
|
||||
alt_client = None
|
||||
if ns['namespace'].startswith(self.alt_project_id):
|
||||
alt_client = \
|
||||
self.os_project_alt_admin.namespace_tags_client
|
||||
client = alt_client
|
||||
if alt_client is None:
|
||||
client = self.os_project_admin.namespace_tags_client
|
||||
tag_name = "tag_of_%s" % (ns['namespace'])
|
||||
namespace_tag = client.create_namespace_tag(
|
||||
ns['namespace'], tag_name=tag_name)
|
||||
|
||||
tag = {'namespace': ns, 'tag': namespace_tag}
|
||||
namespace_tags.append(tag)
|
||||
|
||||
return namespace_tags
|
||||
|
||||
def assertTagsList(self, actual_tag, client, owner=None):
|
||||
ns = actual_tag['namespace']
|
||||
if owner:
|
||||
if not (ns['visibility'] == 'public' or ns['owner'] == owner):
|
||||
self.do_request('list_namespace_tags',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_tags',
|
||||
expected_status=200,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
self.assertEqual(actual_tag['tag']['name'],
|
||||
resp['tags'][0]['name'])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_tags',
|
||||
expected_status=200,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
self.assertEqual(actual_tag['tag']['name'],
|
||||
resp['tags'][0]['name'])
|
||||
|
||||
|
||||
class MetadefV2RbacTagsTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_tag(self):
|
||||
"""Test add_metadef_tag policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_tags(self):
|
||||
"""Test get_metadef_tag policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_tags(self):
|
||||
"""Test list_metadef_tags policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_update_tags(self):
|
||||
"""Test update_metadef_tag policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_tags(self):
|
||||
"""Test delete_metadef_tag policy."""
|
||||
pass
|
||||
|
@@ -1,263 +0,0 @@
|
||||
# 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.
|
||||
|
||||
import abc
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
|
||||
|
||||
|
||||
class MetadefV2RbacNamespaceTest(rbac_base.RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacNamespaceTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespaces_client.project_id
|
||||
cls.alt_project_id = cls.alt_persona.namespaces_client.project_id
|
||||
cls.admin_namespace_client = cls.os_project_admin.namespaces_client
|
||||
cls.namespace_client = cls.persona.namespaces_client
|
||||
cls.alt_namespace_client = cls.alt_persona.namespaces_client
|
||||
|
||||
def assertListNamespaces(self, actual, expected, owner=None):
|
||||
expected_ns = set(ns['namespace'] for ns in expected['namespaces'])
|
||||
if owner:
|
||||
for ns in actual:
|
||||
if (ns['visibility'] == 'private' and
|
||||
ns['owner'] != owner):
|
||||
self.assertNotIn(ns['namespace'], expected_ns)
|
||||
else:
|
||||
self.assertIn(ns['namespace'], expected_ns)
|
||||
else:
|
||||
for ns in actual:
|
||||
self.assertIn(ns['namespace'], expected_ns)
|
||||
|
||||
|
||||
class MetadefV2RbacNamespaceTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_namespace(self):
|
||||
"""Test get_metadef_namespace policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_namespaces(self):
|
||||
"""Test get_metadef_namespaces policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_update_namespace(self):
|
||||
"""Test modify_metadef_namespace policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_namespace(self):
|
||||
"""Test add_metadef_namespace policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_namespace(self):
|
||||
"""Test delete_metadef_namespace policy."""
|
||||
pass
|
||||
|
||||
|
||||
class ProjectAdminTests(MetadefV2RbacNamespaceTest,
|
||||
MetadefV2RbacNamespaceTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_list_namespaces(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Get above created namespace by admin role
|
||||
resp = self.do_request('list_namespaces', expected_status=200,
|
||||
client=self.admin_namespace_client)
|
||||
|
||||
self.assertListNamespaces(actual_namespaces, resp)
|
||||
|
||||
def test_get_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Get above created namespace by admin role
|
||||
for ns in actual_namespaces:
|
||||
resp = self.do_request('show_namespace', expected_status=200,
|
||||
namespace=ns['namespace'],
|
||||
client=self.admin_namespace_client)
|
||||
self.assertEqual(ns['namespace'], resp['namespace'])
|
||||
|
||||
def test_create_namespace(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create namespaces seperately.
|
||||
pass
|
||||
|
||||
def test_update_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Updating the above created namespace by admin role
|
||||
for ns in actual_namespaces:
|
||||
resp = self.do_request(
|
||||
'update_namespace', expected_status=200,
|
||||
namespace=ns['namespace'],
|
||||
client=self.admin_namespace_client,
|
||||
description=data_utils.arbitrary_string(base_text="updated"))
|
||||
self.assertNotEqual(ns['description'], resp['description'])
|
||||
|
||||
def test_delete_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Deleting the above created namespace by admin role
|
||||
for ns in actual_namespaces:
|
||||
self.do_request('delete_namespace', expected_status=204,
|
||||
namespace=ns['namespace'],
|
||||
client=self.admin_namespace_client,)
|
||||
|
||||
# Verify the namespaces are deleted successfully
|
||||
self.do_request('show_namespace',
|
||||
expected_status=exceptions.NotFound,
|
||||
namespace=ns['namespace'],
|
||||
client=self.admin_namespace_client,)
|
||||
|
||||
|
||||
class ProjectMemberTests(MetadefV2RbacNamespaceTest,
|
||||
MetadefV2RbacNamespaceTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_get_namespace(self):
|
||||
|
||||
def assertGetNamespace(actual_ns, owner, client):
|
||||
expected_status = 200
|
||||
if (actual_ns['visibility'] == 'private' and
|
||||
actual_ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('show_namespace',
|
||||
expected_status=expected_status,
|
||||
client=client,
|
||||
namespace=actual_ns['namespace'])
|
||||
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Get namespace - member role from 'project' can access all
|
||||
# namespaces of it's own & only public namespace of 'alt_project'
|
||||
for actual_ns in actual_namespaces:
|
||||
assertGetNamespace(actual_ns, self.project_id,
|
||||
self.namespace_client)
|
||||
|
||||
# Get namespace - member role from 'alt_project' can access all
|
||||
# namespaces of it's own & only public namespace of 'project'
|
||||
for actual_ns in actual_namespaces:
|
||||
assertGetNamespace(actual_ns, self.alt_project_id,
|
||||
self.alt_namespace_client)
|
||||
|
||||
def test_list_namespaces(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# List namespace - member role from 'project' can access all
|
||||
# namespaces of it's own & only public namespace of 'alt_project'
|
||||
resp = self.do_request('list_namespaces',
|
||||
client=self.namespace_client,
|
||||
expected_status=200)
|
||||
self.assertListNamespaces(actual_namespaces, resp, self.project_id)
|
||||
|
||||
# List namespace - member role from 'alt_project' can access all
|
||||
# namespaces of it's own & only public namespace of 'project'
|
||||
resp = self.do_request('list_namespaces',
|
||||
client=self.alt_namespace_client,
|
||||
expected_status=200)
|
||||
self.assertListNamespaces(actual_namespaces, resp, self.alt_project_id)
|
||||
|
||||
def test_update_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
def assertUpdateNamespace(actual_ns, owner, client):
|
||||
expected_status = exceptions.Forbidden
|
||||
if not (actual_ns['visibility'] == 'public' or
|
||||
actual_ns['owner'] == owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('update_namespace',
|
||||
expected_status=expected_status,
|
||||
client=client,
|
||||
description=data_utils.arbitrary_string(),
|
||||
namespace=actual_ns['namespace'])
|
||||
|
||||
# Check member role of 'project' is forbidden to update namespace
|
||||
for actual_ns in actual_namespaces:
|
||||
assertUpdateNamespace(actual_ns, self.project_id,
|
||||
self.namespace_client)
|
||||
|
||||
# Check member role of 'alt_project' is forbidden to update namespace
|
||||
for actual_ns in actual_namespaces:
|
||||
assertUpdateNamespace(actual_ns, self.alt_project_id,
|
||||
self.alt_namespace_client)
|
||||
|
||||
def test_create_namespace(self):
|
||||
# Check non-admin role of 'project' not allowed to create namespace
|
||||
self.do_request('create_namespace',
|
||||
expected_status=exceptions.Forbidden,
|
||||
client=self.namespace_client,
|
||||
namespace=data_utils.arbitrary_string())
|
||||
|
||||
# Check non-admin role of 'alt_project' not allowed to create namespace
|
||||
self.do_request('create_namespace',
|
||||
expected_status=exceptions.Forbidden,
|
||||
client=self.alt_namespace_client,
|
||||
namespace=data_utils.arbitrary_string())
|
||||
|
||||
def test_delete_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
def assertDeleteNamespace(actual_ns, owner, client):
|
||||
expected_status = exceptions.Forbidden
|
||||
if not (actual_ns['visibility'] == 'public' or
|
||||
actual_ns['owner'] == owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('delete_namespace',
|
||||
expected_status=expected_status,
|
||||
client=client,
|
||||
namespace=actual_ns['namespace'])
|
||||
|
||||
# Check member role of 'project' is forbidden to delete namespace
|
||||
for actual_ns in actual_namespaces:
|
||||
assertDeleteNamespace(actual_ns, self.project_id,
|
||||
self.namespace_client)
|
||||
|
||||
# Check member role of 'alt_project' is forbidden to delete namespace
|
||||
for actual_ns in actual_namespaces:
|
||||
assertDeleteNamespace(actual_ns, self.alt_project_id,
|
||||
self.alt_namespace_client)
|
||||
|
||||
# Verify the namespaces are not deleted
|
||||
for actual_ns in actual_namespaces:
|
||||
self.do_request('show_namespace',
|
||||
expected_status=200,
|
||||
client=self.admin_namespace_client,
|
||||
namespace=actual_ns['namespace'])
|
||||
|
||||
|
||||
class ProjectReaderTests(ProjectMemberTests):
|
||||
credentials = ['project_reader', 'project_alt_reader',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
@@ -1,294 +0,0 @@
|
||||
# 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.
|
||||
|
||||
import abc
|
||||
|
||||
from tempest.common import tempest_fixtures as fixtures
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
|
||||
|
||||
|
||||
class MetadefV2RbacObjectsTest(rbac_base.RbacMetadefBase):
|
||||
def setUp(self):
|
||||
# NOTE(pdeore): As we are using global data there is a possibility
|
||||
# of invalid results if these tests are executed concurrently, to avoid
|
||||
# such conflicts we are using locking to execute metadef tests
|
||||
# serially.
|
||||
self.useFixture(fixtures.LockFixture('metadef_namespaces'))
|
||||
super(MetadefV2RbacObjectsTest, self).setUp()
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacObjectsTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespace_objects_client.project_id
|
||||
cls.alt_project_id = \
|
||||
cls.alt_persona.namespace_objects_client.project_id
|
||||
cls.objects_client = cls.persona.namespace_objects_client
|
||||
|
||||
def create_objects(self):
|
||||
# Create namespace for two different projects
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
client = self.os_project_admin.namespace_objects_client
|
||||
namespace_objects = []
|
||||
for ns in namespaces:
|
||||
if ns['namespace'].startswith(self.project_id):
|
||||
client = self.os_project_alt_admin.namespace_objects_client
|
||||
object_name = "object_of_%s" % (ns['namespace'])
|
||||
namespace_object = client.create_namespace_object(
|
||||
ns['namespace'], name=object_name,
|
||||
description=data_utils.arbitrary_string())
|
||||
|
||||
obj = {'namespace': ns, 'object': namespace_object}
|
||||
namespace_objects.append(obj)
|
||||
|
||||
return namespace_objects
|
||||
|
||||
def assertObjectsList(self, actual_obj, client, owner=None):
|
||||
ns = actual_obj['namespace']
|
||||
if owner:
|
||||
if not (ns['visibility'] == 'public' or
|
||||
ns['owner'] == owner):
|
||||
self.do_request('list_namespace_objects',
|
||||
expected_status=exceptions.NotFound,
|
||||
namespace=ns['namespace'],
|
||||
client=client)
|
||||
else:
|
||||
resp = self.do_request('list_namespace_objects',
|
||||
expected_status=200,
|
||||
namespace=ns['namespace'],
|
||||
client=client)
|
||||
self.assertIn(actual_obj['object']['name'],
|
||||
resp['objects'][0]['name'])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_objects',
|
||||
expected_status=200,
|
||||
namespace=ns['namespace'],
|
||||
client=client)
|
||||
self.assertIn(actual_obj['object']['name'],
|
||||
resp['objects'][0]['name'])
|
||||
|
||||
|
||||
class MetadefV2RbacObjectsTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_object(self):
|
||||
"""Test add_metadef_object policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_object(self):
|
||||
"""Test get_metadef_object policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_objects(self):
|
||||
"""Test list_metadef_objects policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_update_object(self):
|
||||
"""Test update_metadef_object policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_object(self):
|
||||
"""Test delete_metadef_object policy."""
|
||||
pass
|
||||
|
||||
|
||||
class ProjectAdminTests(MetadefV2RbacObjectsTest,
|
||||
MetadefV2RbacObjectsTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_get_object(self):
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# Get all metadef objects with admin role
|
||||
for obj in ns_objects:
|
||||
resp = self.do_request(
|
||||
'show_namespace_object',
|
||||
expected_status=200,
|
||||
client=self.objects_client,
|
||||
namespace=obj['namespace']['namespace'],
|
||||
object_name=obj['object']['name'])
|
||||
self.assertEqual(obj['object']['name'], resp['name'])
|
||||
|
||||
def test_list_objects(self):
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# list all metadef objects with admin role
|
||||
for obj in ns_objects:
|
||||
self.assertObjectsList(obj, self.objects_client)
|
||||
|
||||
def test_update_object(self):
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# update all metadef objects with admin role of 'project'
|
||||
for obj in ns_objects:
|
||||
resp = self.do_request(
|
||||
'update_namespace_object',
|
||||
expected_status=200,
|
||||
namespace=obj['namespace']['namespace'],
|
||||
client=self.objects_client,
|
||||
object_name=obj['object']['name'],
|
||||
name=obj['object']['name'],
|
||||
description=data_utils.arbitrary_string(base_text="updated"))
|
||||
self.assertNotEqual(obj['object']['description'],
|
||||
resp['description'])
|
||||
|
||||
def test_delete_object(self):
|
||||
ns_objects = self.create_objects()
|
||||
# delete all metadef objects with admin role of 'project'
|
||||
for obj in ns_objects:
|
||||
self.do_request('delete_namespace_object',
|
||||
expected_status=204,
|
||||
namespace=obj['namespace']['namespace'],
|
||||
object_name=obj['object']['name'],
|
||||
client=self.objects_client)
|
||||
|
||||
# Verify the object is deleted successfully
|
||||
self.do_request('show_namespace_object',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=self.objects_client,
|
||||
namespace=obj['namespace']['namespace'],
|
||||
object_name=obj['object']['name'])
|
||||
|
||||
def test_create_object(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create objects seperately.
|
||||
pass
|
||||
|
||||
|
||||
class ProjectMemberTests(MetadefV2RbacObjectsTest,
|
||||
MetadefV2RbacObjectsTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member', 'project_admin',
|
||||
'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_object(self):
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
def assertCreateObjects(namespace, owner, client):
|
||||
object_name = "object_of_%s" % (namespace['namespace'])
|
||||
expected_status = exceptions.Forbidden
|
||||
if (namespace['visibility'] == 'private' and
|
||||
namespace['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('create_namespace_object',
|
||||
expected_status=expected_status,
|
||||
namespace=namespace['namespace'],
|
||||
name=object_name,
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' forbidden to
|
||||
# create objects
|
||||
for namespace in namespaces:
|
||||
assertCreateObjects(namespace, self.project_id,
|
||||
self.objects_client)
|
||||
|
||||
def test_get_object(self):
|
||||
|
||||
def assertObjectGet(actual_obj, owner, client):
|
||||
ns = actual_obj['namespace']
|
||||
expected_status = 200
|
||||
if (ns['visibility'] == 'private' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('show_namespace_object',
|
||||
expected_status=expected_status,
|
||||
namespace=actual_obj['namespace']['namespace'],
|
||||
object_name=actual_obj['object']['name'],
|
||||
client=client)
|
||||
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# Get object - member role from 'project' can access all
|
||||
# objects of it's own & only objects having public namespace of
|
||||
# 'alt_project'
|
||||
for obj in ns_objects:
|
||||
assertObjectGet(obj, self.project_id, self.objects_client)
|
||||
|
||||
def test_list_objects(self):
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# list objects - member role from 'project' can access all
|
||||
# objects of it's own & only objects having public namespace of
|
||||
# 'alt_project'
|
||||
for obj in ns_objects:
|
||||
self.assertObjectsList(obj, self.objects_client, self.project_id)
|
||||
|
||||
def test_update_object(self):
|
||||
|
||||
def assertObjectUpdate(actual_object, owner, client):
|
||||
ns = actual_object['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] == 'private' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('update_namespace_object',
|
||||
expected_status=expected_status,
|
||||
name=actual_object['object']['name'],
|
||||
description=data_utils.arbitrary_string(),
|
||||
namespace=actual_object['namespace']['namespace'],
|
||||
object_name=actual_object['object']['name'],
|
||||
client=client)
|
||||
|
||||
ns_objects = self.create_objects()
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# update objects
|
||||
for obj in ns_objects:
|
||||
assertObjectUpdate(obj, self.project_id, self.objects_client)
|
||||
|
||||
def test_delete_object(self):
|
||||
|
||||
def assertObjectDelete(actual_obj, owner, client):
|
||||
ns = actual_obj['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] == 'private' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('delete_namespace_object',
|
||||
expected_status=expected_status,
|
||||
namespace=actual_obj['namespace']['namespace'],
|
||||
object_name=actual_obj['object']['name'],
|
||||
client=client)
|
||||
|
||||
ns_objects = self.create_objects()
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete objects
|
||||
for obj in ns_objects:
|
||||
assertObjectDelete(obj, self.project_id, self.objects_client)
|
||||
|
||||
|
||||
class ProjectReaderTests(ProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_alt_reader', 'project_admin',
|
||||
'project_alt_admin', 'primary']
|
@@ -1,297 +0,0 @@
|
||||
# Copyright 2021 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.
|
||||
|
||||
import abc
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
|
||||
|
||||
|
||||
class MetadefV2RbacPropertiesTest(rbac_base.RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacPropertiesTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespaces_client.project_id
|
||||
cls.alt_project_id = cls.alt_persona.namespaces_client.project_id
|
||||
cls.properties_client = cls.persona.namespace_properties_client
|
||||
|
||||
def create_properties(self):
|
||||
# Create namespace for two different projects
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
namespace_properties = []
|
||||
for ns in namespaces:
|
||||
alt_client = None
|
||||
if ns['namespace'].startswith(self.alt_project_id):
|
||||
alt_client = \
|
||||
self.os_project_alt_admin.namespace_properties_client
|
||||
client = alt_client
|
||||
if alt_client is None:
|
||||
client = self.os_project_admin.namespace_properties_client
|
||||
|
||||
property_name = "prop_of_%s" % (ns['namespace'])
|
||||
namespace_property = client.create_namespace_property(
|
||||
ns['namespace'], name=property_name, title='property',
|
||||
type='integer')
|
||||
|
||||
prop = {'namespace': ns, 'property': namespace_property}
|
||||
namespace_properties.append(prop)
|
||||
|
||||
return namespace_properties
|
||||
|
||||
def assertPropertyList(self, actual_prop, client, owner=None):
|
||||
ns = actual_prop['namespace']
|
||||
if owner:
|
||||
if not (ns['visibility'] == 'public' or ns['owner'] == owner):
|
||||
resp = self.do_request('list_namespace_properties',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_properties',
|
||||
expected_status=200,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
self.assertEqual(actual_prop['property']['name'],
|
||||
[*resp['properties']][0])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_properties',
|
||||
expected_status=200,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
self.assertEqual(actual_prop['property']['name'],
|
||||
[*resp['properties']][0])
|
||||
|
||||
|
||||
class MetadefV2RbacPropertiesTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_property(self):
|
||||
"""Test add_metadef_property policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_properties(self):
|
||||
"""Test get_metadef_property policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_properties(self):
|
||||
"""Test list_metadef_properties policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_update_properties(self):
|
||||
"""Test update_metadef_property policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_properties(self):
|
||||
"""Test delete_metadef_property policy."""
|
||||
pass
|
||||
|
||||
|
||||
class ProjectAdminTests(MetadefV2RbacPropertiesTest,
|
||||
MetadefV2RbacPropertiesTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_property(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create properties separately.
|
||||
pass
|
||||
|
||||
def test_get_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
# Get all metadef properties with admin role of 'project'
|
||||
for prop in ns_properties:
|
||||
resp = self.do_request(
|
||||
'show_namespace_properties',
|
||||
expected_status=200,
|
||||
client=self.properties_client,
|
||||
namespace=prop['namespace']['namespace'],
|
||||
property_name=prop['property']['name'])
|
||||
self.assertEqual(prop['property'], resp)
|
||||
|
||||
def test_list_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
# list all metadef properties with admin role of 'project'
|
||||
for prop in ns_properties:
|
||||
self.assertPropertyList(prop, self.properties_client)
|
||||
|
||||
def test_update_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
# update all metadef properties with admin role of 'project'
|
||||
for prop in ns_properties:
|
||||
resp = self.do_request(
|
||||
'update_namespace_properties',
|
||||
expected_status=200,
|
||||
namespace=prop['namespace']['namespace'],
|
||||
client=self.properties_client,
|
||||
title="UPDATE_Property",
|
||||
property_name=prop['property']['name'],
|
||||
name=prop['property']['name'],
|
||||
type="string")
|
||||
self.assertNotEqual(prop['property']['title'],
|
||||
resp['title'])
|
||||
|
||||
def test_delete_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
# delete all metadef properties with admin role of 'project'
|
||||
for prop in ns_properties:
|
||||
self.do_request('delete_namespace_property',
|
||||
expected_status=204,
|
||||
namespace=prop['namespace']['namespace'],
|
||||
property_name=prop['property']['name'],
|
||||
client=self.properties_client)
|
||||
|
||||
# Verify the property is deleted successfully
|
||||
self.do_request('show_namespace_properties',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=self.properties_client,
|
||||
namespace=prop['namespace']['namespace'],
|
||||
property_name=prop['property']['name'])
|
||||
|
||||
|
||||
class ProjectMemberTests(MetadefV2RbacPropertiesTest,
|
||||
MetadefV2RbacPropertiesTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_property(self):
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
def assertPropertyCreate(namespace, client, owner=None):
|
||||
property_name = "prop_of_%s" % (namespace['namespace'])
|
||||
expected_status = exceptions.Forbidden
|
||||
if not (namespace['visibility'] == 'public' or
|
||||
namespace['owner'] == owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('create_namespace_property',
|
||||
expected_status=expected_status,
|
||||
namespace=namespace['namespace'],
|
||||
title="property",
|
||||
type='integer',
|
||||
name=property_name,
|
||||
client=client)
|
||||
# Make sure non admin role of 'project' forbidden to
|
||||
# create properties
|
||||
for namespace in namespaces:
|
||||
assertPropertyCreate(namespace, self.properties_client,
|
||||
self.project_id)
|
||||
|
||||
def test_get_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
def assertPropertyGet(actual_prop, client, owner=None):
|
||||
ns = actual_prop['namespace']
|
||||
expected_status = 200
|
||||
if (ns['visibility'] != 'public' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('show_namespace_properties',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
property_name=actual_prop['property']['name'],
|
||||
client=client)
|
||||
|
||||
# Get property - member role from 'project' can access all
|
||||
# properties of it's own & only propertys having public namespace of
|
||||
# 'alt_project'
|
||||
for prop in ns_properties:
|
||||
assertPropertyGet(prop, self.properties_client, self.project_id)
|
||||
|
||||
def test_list_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
# list properties - member role from 'project' can access all
|
||||
# properties of it's own & only propertys having public namespace of
|
||||
# 'alt_project'
|
||||
for prop in ns_properties:
|
||||
self.assertPropertyList(prop, self.properties_client,
|
||||
self.project_id)
|
||||
|
||||
def test_update_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
def assertPropertyUpdate(actual_prop, client, owner=None):
|
||||
ns = actual_prop['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('update_namespace_properties',
|
||||
expected_status=expected_status,
|
||||
name=actual_prop['property']['name'],
|
||||
description=data_utils.arbitrary_string(),
|
||||
namespace=ns['namespace'],
|
||||
property_name=actual_prop['property']['name'],
|
||||
title="UPDATE_Property",
|
||||
type="string",
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# update properties
|
||||
for prop in ns_properties:
|
||||
assertPropertyUpdate(prop, self.properties_client,
|
||||
self.project_id)
|
||||
|
||||
def test_delete_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
def assertPropertyDelete(actual_prop, client, owner=None):
|
||||
ns = actual_prop['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('delete_namespace_property',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
property_name=actual_prop['property']['name'],
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete properties
|
||||
for prop in ns_properties:
|
||||
assertPropertyDelete(prop, self.properties_client,
|
||||
self.project_id)
|
||||
|
||||
|
||||
class ProjectReaderTests(ProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_alt_reader',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
@@ -1,240 +0,0 @@
|
||||
# Copyright 2021 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.
|
||||
|
||||
import abc
|
||||
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
|
||||
|
||||
|
||||
class MetadefV2RbacResourceTypeTest(rbac_base.RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacResourceTypeTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespaces_client.project_id
|
||||
cls.alt_project_id = cls.alt_persona.namespaces_client.project_id
|
||||
cls.resource_types_client = cls.persona.resource_types_client
|
||||
|
||||
def create_resource_types(self):
|
||||
# Create namespace for two different projects
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
namespace_resource_types = []
|
||||
for ns in namespaces:
|
||||
alt_client = None
|
||||
if ns['namespace'].startswith(self.alt_project_id):
|
||||
alt_client = self.os_project_alt_admin.resource_types_client
|
||||
client = alt_client
|
||||
if alt_client is None:
|
||||
client = self.os_project_admin.resource_types_client
|
||||
resource_name = "rs_type_of_%s" % (ns['namespace'])
|
||||
resource_type = client.create_resource_type_association(
|
||||
ns['namespace'], name=resource_name)
|
||||
resource_types = {'namespace': ns,
|
||||
'resource_type': resource_type}
|
||||
namespace_resource_types.append(resource_types)
|
||||
|
||||
return namespace_resource_types
|
||||
|
||||
def assertRSTypeList(self, ns_rs_types, resp):
|
||||
actual_rs_types = set(rt['name'] for rt in resp['resource_types'])
|
||||
|
||||
for rs_type in ns_rs_types:
|
||||
self.assertIn(rs_type['resource_type']['name'],
|
||||
actual_rs_types)
|
||||
|
||||
|
||||
class MetadefV2RbacResourceTypeTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_resource_type(self):
|
||||
"""Test add_metadef_resource_type_association policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_resource_type(self):
|
||||
"""Test get_metadef_resource_type policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_resource_types(self):
|
||||
"""Test list_metadef_resource_types policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_resource_type(self):
|
||||
"""Test remove_metadef_resource_type_association policy."""
|
||||
pass
|
||||
|
||||
|
||||
class ProjectAdminTests(MetadefV2RbacResourceTypeTest,
|
||||
MetadefV2RbacResourceTypeTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_resource_type(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create resource types separately.
|
||||
pass
|
||||
|
||||
def test_get_resource_type(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
# Get all metadef resource types with admin role of 'project'
|
||||
for rs_type in ns_rs_types:
|
||||
resp = self.do_request(
|
||||
'list_resource_type_association',
|
||||
expected_status=200,
|
||||
client=self.resource_types_client,
|
||||
namespace_id=rs_type['namespace']['namespace'])
|
||||
self.assertEqual(rs_type['resource_type']['name'],
|
||||
resp['resource_type_associations'][0]['name'])
|
||||
|
||||
def test_list_resource_types(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
# list resource types - with admin role of 'project'
|
||||
resp = self.do_request('list_resource_types',
|
||||
expected_status=200,
|
||||
client=self.resource_types_client)
|
||||
|
||||
# Verify that admin role of 'project' will be able to view available
|
||||
# resource types
|
||||
self.assertRSTypeList(ns_rs_types, resp)
|
||||
|
||||
def test_delete_resource_type(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
# delete all metadef resource types with admin role of 'project'
|
||||
for rs_type in ns_rs_types:
|
||||
self.do_request('delete_resource_type_association',
|
||||
expected_status=204,
|
||||
namespace_id=rs_type['namespace']['namespace'],
|
||||
resource_name=rs_type['resource_type']['name'],
|
||||
client=self.resource_types_client)
|
||||
|
||||
# Verify the resource types is deleted successfully
|
||||
resp = self.do_request(
|
||||
'list_resource_type_association', expected_status=200,
|
||||
client=self.resource_types_client,
|
||||
namespace_id=rs_type['namespace']['namespace'])
|
||||
self.assertEqual([], resp['resource_type_associations'])
|
||||
|
||||
|
||||
class ProjectMemberTests(MetadefV2RbacResourceTypeTest,
|
||||
MetadefV2RbacResourceTypeTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member', 'project_admin',
|
||||
'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_resource_type(self):
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
def assertRSTypeCreate(namespace, owner, client):
|
||||
rs_type_name = "rs_type_of_%s" % (namespace['namespace'])
|
||||
expected_status = exceptions.Forbidden
|
||||
if (namespace['visibility'] != 'public' and
|
||||
namespace['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('create_resource_type_association',
|
||||
expected_status=expected_status,
|
||||
namespace_id=namespace['namespace'],
|
||||
name=rs_type_name,
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' forbidden to
|
||||
# create resource types
|
||||
for namespace in namespaces:
|
||||
assertRSTypeCreate(namespace, self.project_id,
|
||||
self.resource_types_client)
|
||||
|
||||
def test_get_resource_type(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
def assertRSTypeGet(actual_rs_type, client, owner):
|
||||
ns = actual_rs_type['namespace']
|
||||
expected_status = 200
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('list_resource_type_association',
|
||||
expected_status=expected_status,
|
||||
namespace_id=ns['namespace'],
|
||||
client=client)
|
||||
|
||||
# Get resource type - member role from 'project' can access all
|
||||
# resource types of it's own & only resource types having public
|
||||
# namespace of 'alt_project'
|
||||
for rs_type in ns_rs_types:
|
||||
assertRSTypeGet(rs_type, self.resource_types_client,
|
||||
self.project_id)
|
||||
|
||||
def test_list_resource_types(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
# list resource types - with member role of 'project'
|
||||
resp = self.do_request('list_resource_types',
|
||||
expected_status=200,
|
||||
client=self.resource_types_client)
|
||||
|
||||
# Verify that member role of 'project' will be able to view available
|
||||
# resource types
|
||||
self.assertRSTypeList(ns_rs_types, resp)
|
||||
|
||||
# list resource types - with member role of 'alt_project'
|
||||
resp = self.do_request('list_resource_types',
|
||||
expected_status=200,
|
||||
client=self.resource_types_client)
|
||||
|
||||
def test_delete_resource_type(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
def assertRSTypeDelete(actual_rs_type, client, owner):
|
||||
ns = actual_rs_type['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request(
|
||||
'delete_resource_type_association',
|
||||
expected_status=expected_status,
|
||||
namespace_id=ns['namespace'],
|
||||
resource_name=actual_rs_type['resource_type']['name'],
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete resource types
|
||||
for rs_type in ns_rs_types:
|
||||
assertRSTypeDelete(rs_type, self.resource_types_client,
|
||||
self.project_id)
|
||||
|
||||
|
||||
class ProjectReaderTests(ProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_alt_reader', 'project_admin',
|
||||
'project_alt_admin', 'primary']
|
@@ -1,353 +0,0 @@
|
||||
# Copyright 2021 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.
|
||||
|
||||
import abc
|
||||
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
|
||||
|
||||
|
||||
class MetadefV2RbacTagsTest(rbac_base.RbacMetadefBase):
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(MetadefV2RbacTagsTest, cls).setup_clients()
|
||||
if 'project_member' in cls.credentials:
|
||||
persona = 'project_member'
|
||||
alt_persona = 'project_alt_member'
|
||||
elif 'project_reader' in cls.credentials:
|
||||
persona = 'project_reader'
|
||||
alt_persona = 'project_alt_reader'
|
||||
else:
|
||||
persona = 'project_admin'
|
||||
alt_persona = 'project_alt_admin'
|
||||
cls.persona = getattr(cls, 'os_%s' % persona)
|
||||
cls.alt_persona = getattr(cls, 'os_%s' % alt_persona)
|
||||
cls.project_id = cls.persona.namespaces_client.project_id
|
||||
cls.alt_project_id = cls.alt_persona.namespaces_client.project_id
|
||||
cls.tags_client = cls.persona.namespace_tags_client
|
||||
|
||||
def create_tags(self, namespaces, multiple_tags=False):
|
||||
namespace_tags = []
|
||||
|
||||
if multiple_tags:
|
||||
tags = [{"name": "tag1"}, {"name": "tag2"}, {"name": "tag3"}]
|
||||
for ns in namespaces:
|
||||
alt_client = None
|
||||
if ns['namespace'].startswith(self.alt_project_id):
|
||||
alt_client = \
|
||||
self.os_project_alt_admin.namespace_tags_client
|
||||
client = alt_client
|
||||
if alt_client is None:
|
||||
client = self.os_project_admin.namespace_tags_client
|
||||
multiple_tags = client.create_namespace_tags(
|
||||
ns['namespace'], tags=tags)
|
||||
|
||||
namespace_multiple_tags = {'namespace': ns,
|
||||
'tags': multiple_tags}
|
||||
namespace_tags.append(namespace_multiple_tags)
|
||||
else:
|
||||
for ns in namespaces:
|
||||
alt_client = None
|
||||
if ns['namespace'].startswith(self.alt_project_id):
|
||||
alt_client = \
|
||||
self.os_project_alt_admin.namespace_tags_client
|
||||
client = alt_client
|
||||
if alt_client is None:
|
||||
client = self.os_project_admin.namespace_tags_client
|
||||
tag_name = "tag_of_%s" % (ns['namespace'])
|
||||
namespace_tag = client.create_namespace_tag(
|
||||
ns['namespace'], tag_name=tag_name)
|
||||
|
||||
tag = {'namespace': ns, 'tag': namespace_tag}
|
||||
namespace_tags.append(tag)
|
||||
|
||||
return namespace_tags
|
||||
|
||||
def assertTagsList(self, actual_tag, client, owner=None):
|
||||
ns = actual_tag['namespace']
|
||||
if owner:
|
||||
if not (ns['visibility'] == 'public' or ns['owner'] == owner):
|
||||
self.do_request('list_namespace_tags',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_tags',
|
||||
expected_status=200,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
self.assertEqual(actual_tag['tag']['name'],
|
||||
resp['tags'][0]['name'])
|
||||
else:
|
||||
resp = self.do_request('list_namespace_tags',
|
||||
expected_status=200,
|
||||
client=client,
|
||||
namespace=ns['namespace'])
|
||||
self.assertEqual(actual_tag['tag']['name'],
|
||||
resp['tags'][0]['name'])
|
||||
|
||||
|
||||
class MetadefV2RbacTagsTemplate(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_create_tag(self):
|
||||
"""Test add_metadef_tag policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_get_tags(self):
|
||||
"""Test get_metadef_tag policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_list_tags(self):
|
||||
"""Test list_metadef_tags policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_update_tags(self):
|
||||
"""Test update_metadef_tag policy."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def test_delete_tags(self):
|
||||
"""Test delete_metadef_tag policy."""
|
||||
pass
|
||||
|
||||
|
||||
class ProjectAdminTests(MetadefV2RbacTagsTest,
|
||||
MetadefV2RbacTagsTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_tag(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create properties separately.
|
||||
pass
|
||||
|
||||
def test_get_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
# Get all metadef tags with admin role of 'project'
|
||||
for tag in ns_tags:
|
||||
resp = self.do_request(
|
||||
'show_namespace_tag',
|
||||
expected_status=200,
|
||||
client=self.tags_client,
|
||||
namespace=tag['namespace']['namespace'],
|
||||
tag_name=tag['tag']['name'])
|
||||
self.assertEqual(tag['tag']['name'], resp['name'])
|
||||
|
||||
def test_list_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
# list all metadef tags with admin role of 'project'
|
||||
for tag in ns_tags:
|
||||
self.assertTagsList(tag, self.tags_client)
|
||||
|
||||
def test_update_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
# update all metadef tags with admin role of 'project'
|
||||
for tag in ns_tags:
|
||||
resp = self.do_request(
|
||||
'update_namespace_tag',
|
||||
expected_status=200,
|
||||
namespace=tag['namespace']['namespace'],
|
||||
client=self.tags_client,
|
||||
tag_name=tag['tag']['name'],
|
||||
name=data_utils.arbitrary_string(base_text="updated-name"))
|
||||
self.assertNotEqual(tag['tag']['name'], resp['name'])
|
||||
|
||||
def test_delete_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
def assertDeleteTags(tag, client, multiple_tags=False):
|
||||
namespace = tag['namespace']['namespace']
|
||||
if multiple_tags:
|
||||
self.do_request('delete_namespace_tags',
|
||||
expected_status=204,
|
||||
namespace=namespace,
|
||||
client=client)
|
||||
# Verify the tags are deleted successfully
|
||||
resp = self.do_request('list_namespace_tags',
|
||||
client=client,
|
||||
namespace=namespace)
|
||||
self.assertEqual(0, len(resp['tags']))
|
||||
else:
|
||||
tag_name = tag['tag']['name']
|
||||
self.do_request('delete_namespace_tag',
|
||||
expected_status=204,
|
||||
namespace=namespace,
|
||||
tag_name=tag_name,
|
||||
client=client)
|
||||
|
||||
# Verify the tag is deleted successfully
|
||||
self.do_request('show_namespace_tag',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=client,
|
||||
namespace=namespace,
|
||||
tag_name=tag_name)
|
||||
|
||||
# delete all metadef tags with admin role of 'project'
|
||||
for tag in ns_tags:
|
||||
assertDeleteTags(tag, self.tags_client)
|
||||
|
||||
# Create multiple tags
|
||||
ns_multiple_tags = self.create_tags(namespaces, multiple_tags=True)
|
||||
# delete all metadef multiple tags with admin role of 'project'
|
||||
for tags in ns_multiple_tags:
|
||||
assertDeleteTags(tags, self.tags_client, multiple_tags=True)
|
||||
|
||||
|
||||
class ProjectMemberTests(MetadefV2RbacTagsTest,
|
||||
MetadefV2RbacTagsTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_tag(self):
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
def assertTagsCreate(namespace, client, owner, multiple_tags=False):
|
||||
expected_status = exceptions.Forbidden
|
||||
if (namespace['visibility'] != 'public' and
|
||||
namespace['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
if multiple_tags:
|
||||
multiple_tags = [{"name": "tag1"}, {"name": "tag2"},
|
||||
{"name": "tag3"}]
|
||||
self.do_request('create_namespace_tags',
|
||||
expected_status=expected_status,
|
||||
namespace=namespace['namespace'],
|
||||
tags=multiple_tags,
|
||||
client=client)
|
||||
else:
|
||||
tag_name = "tag_of_%s" % (namespace['namespace'])
|
||||
self.do_request('create_namespace_tag',
|
||||
expected_status=expected_status,
|
||||
namespace=namespace['namespace'],
|
||||
tag_name=tag_name,
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' forbidden to
|
||||
# create tags
|
||||
for namespace in namespaces:
|
||||
assertTagsCreate(namespace, self.tags_client, self.project_id)
|
||||
|
||||
# Create Multiple Tags
|
||||
assertTagsCreate(namespace, self.tags_client, self.project_id,
|
||||
multiple_tags=True)
|
||||
|
||||
def test_get_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
def assertTagGet(actual_tag, client, owner=None):
|
||||
ns = actual_tag['namespace']
|
||||
expected_status = 200
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('show_namespace_tag',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
tag_name=actual_tag['tag']['name'],
|
||||
client=client)
|
||||
|
||||
# Get tag - member role from 'project' can access all
|
||||
# tags of it's own & only tags having public namespace of
|
||||
# 'alt_project'
|
||||
for tag in ns_tags:
|
||||
assertTagGet(tag, self.tags_client, self.project_id)
|
||||
|
||||
def test_list_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
# list tags - member role from 'project' can access all
|
||||
# tags of it's own & only tags having public namespace of
|
||||
# 'alt_project'
|
||||
for tag in ns_tags:
|
||||
self.assertTagsList(tag, self.tags_client, self.project_id)
|
||||
|
||||
def test_update_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
def assertTagUpdate(tag, client, owner):
|
||||
ns = tag['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('update_namespace_tag',
|
||||
expected_status=expected_status,
|
||||
name=data_utils.arbitrary_string(),
|
||||
namespace=tag['namespace']['namespace'],
|
||||
tag_name=tag['tag']['name'],
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# update tags
|
||||
for tag in ns_tags:
|
||||
assertTagUpdate(tag, self.tags_client, self.project_id)
|
||||
|
||||
def test_delete_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
def assertTagsDelete(actual_tag, client, owner, multiple_tags=False):
|
||||
ns = tag['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
if multiple_tags:
|
||||
self.do_request('delete_namespace_tags',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
client=client)
|
||||
else:
|
||||
self.do_request('delete_namespace_tag',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
tag_name=actual_tag['tag']['name'],
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete tags
|
||||
for tag in ns_tags:
|
||||
assertTagsDelete(tag, self.tags_client, self.project_id)
|
||||
|
||||
# Create Multiple Tags
|
||||
ns_multiple_tags = self.create_tags(namespaces, multiple_tags=True)
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete multiple tags
|
||||
for tags in ns_multiple_tags:
|
||||
assertTagsDelete(tags, self.tags_client, self.project_id,
|
||||
multiple_tags=True)
|
||||
|
||||
|
||||
class ProjectReaderTests(ProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_alt_reader',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
@@ -17,14 +17,13 @@ from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from glance_tempest_plugin.tests.rbac.v2.base import ImageV2RbacImageTest
|
||||
from glance_tempest_plugin.tests.rbac.v2.base import ImageV2RbacTemplate
|
||||
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class ProjectAdminTests(ImageV2RbacImageTest,
|
||||
ImageV2RbacTemplate):
|
||||
class ImageProjectAdminTests(rbac_base.ImageV2RbacImageTest,
|
||||
rbac_base.ImageV2RbacTemplate):
|
||||
|
||||
credentials = ['project_admin', 'system_admin', 'project_alt_admin']
|
||||
|
||||
@@ -755,3 +754,331 @@ class ProjectAdminTests(ImageV2RbacImageTest,
|
||||
# system-scope and fail with an appropriate error (e.g., 403)
|
||||
self.do_request('reactivate_image', expected_status=204,
|
||||
image_id=image['id'])
|
||||
|
||||
|
||||
class NamespacesProjectAdminTests(rbac_base.MetadefV2RbacNamespaceTest,
|
||||
rbac_base.MetadefV2RbacNamespaceTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_list_namespaces(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Get above created namespace by admin role
|
||||
resp = self.do_request('list_namespaces', expected_status=200,
|
||||
client=self.admin_namespace_client)
|
||||
|
||||
self.assertListNamespaces(actual_namespaces, resp)
|
||||
|
||||
def test_get_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Get above created namespace by admin role
|
||||
for ns in actual_namespaces:
|
||||
resp = self.do_request('show_namespace', expected_status=200,
|
||||
namespace=ns['namespace'],
|
||||
client=self.admin_namespace_client)
|
||||
self.assertEqual(ns['namespace'], resp['namespace'])
|
||||
|
||||
def test_create_namespace(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create namespaces seperately.
|
||||
pass
|
||||
|
||||
def test_update_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Updating the above created namespace by admin role
|
||||
for ns in actual_namespaces:
|
||||
resp = self.do_request(
|
||||
'update_namespace', expected_status=200,
|
||||
namespace=ns['namespace'],
|
||||
client=self.admin_namespace_client,
|
||||
description=data_utils.arbitrary_string(base_text="updated"))
|
||||
self.assertNotEqual(ns['description'], resp['description'])
|
||||
|
||||
def test_delete_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Deleting the above created namespace by admin role
|
||||
for ns in actual_namespaces:
|
||||
self.do_request('delete_namespace', expected_status=204,
|
||||
namespace=ns['namespace'],
|
||||
client=self.admin_namespace_client,)
|
||||
|
||||
# Verify the namespaces are deleted successfully
|
||||
self.do_request('show_namespace',
|
||||
expected_status=exceptions.NotFound,
|
||||
namespace=ns['namespace'],
|
||||
client=self.admin_namespace_client,)
|
||||
|
||||
|
||||
class RSTypesProjectAdminTests(rbac_base.MetadefV2RbacResourceTypeTest,
|
||||
rbac_base.MetadefV2RbacResourceTypeTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_resource_type(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create resource types separately.
|
||||
pass
|
||||
|
||||
def test_get_resource_type(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
# Get all metadef resource types with admin role of 'project'
|
||||
for rs_type in ns_rs_types:
|
||||
resp = self.do_request(
|
||||
'list_resource_type_association',
|
||||
expected_status=200,
|
||||
client=self.resource_types_client,
|
||||
namespace_id=rs_type['namespace']['namespace'])
|
||||
self.assertEqual(rs_type['resource_type']['name'],
|
||||
resp['resource_type_associations'][0]['name'])
|
||||
|
||||
def test_list_resource_types(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
# list resource types - with admin role of 'project'
|
||||
resp = self.do_request('list_resource_types',
|
||||
expected_status=200,
|
||||
client=self.resource_types_client)
|
||||
|
||||
# Verify that admin role of 'project' will be able to view available
|
||||
# resource types
|
||||
self.assertRSTypeList(ns_rs_types, resp)
|
||||
|
||||
def test_delete_resource_type(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
# delete all metadef resource types with admin role of 'project'
|
||||
for rs_type in ns_rs_types:
|
||||
self.do_request('delete_resource_type_association',
|
||||
expected_status=204,
|
||||
namespace_id=rs_type['namespace']['namespace'],
|
||||
resource_name=rs_type['resource_type']['name'],
|
||||
client=self.resource_types_client)
|
||||
|
||||
# Verify the resource types is deleted successfully
|
||||
resp = self.do_request(
|
||||
'list_resource_type_association', expected_status=200,
|
||||
client=self.resource_types_client,
|
||||
namespace_id=rs_type['namespace']['namespace'])
|
||||
self.assertEqual([], resp['resource_type_associations'])
|
||||
|
||||
|
||||
class ObjectsProjectAdminTests(rbac_base.MetadefV2RbacObjectsTest,
|
||||
rbac_base.MetadefV2RbacObjectsTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_get_object(self):
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# Get all metadef objects with admin role
|
||||
for obj in ns_objects:
|
||||
resp = self.do_request(
|
||||
'show_namespace_object',
|
||||
expected_status=200,
|
||||
client=self.objects_client,
|
||||
namespace=obj['namespace']['namespace'],
|
||||
object_name=obj['object']['name'])
|
||||
self.assertEqual(obj['object']['name'], resp['name'])
|
||||
|
||||
def test_list_objects(self):
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# list all metadef objects with admin role
|
||||
for obj in ns_objects:
|
||||
self.assertObjectsList(obj, self.objects_client)
|
||||
|
||||
def test_update_object(self):
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# update all metadef objects with admin role of 'project'
|
||||
for obj in ns_objects:
|
||||
resp = self.do_request(
|
||||
'update_namespace_object',
|
||||
expected_status=200,
|
||||
namespace=obj['namespace']['namespace'],
|
||||
client=self.objects_client,
|
||||
object_name=obj['object']['name'],
|
||||
name=obj['object']['name'],
|
||||
description=data_utils.arbitrary_string(base_text="updated"))
|
||||
self.assertNotEqual(obj['object']['description'],
|
||||
resp['description'])
|
||||
|
||||
def test_delete_object(self):
|
||||
ns_objects = self.create_objects()
|
||||
# delete all metadef objects with admin role of 'project'
|
||||
for obj in ns_objects:
|
||||
self.do_request('delete_namespace_object',
|
||||
expected_status=204,
|
||||
namespace=obj['namespace']['namespace'],
|
||||
object_name=obj['object']['name'],
|
||||
client=self.objects_client)
|
||||
|
||||
# Verify the object is deleted successfully
|
||||
self.do_request('show_namespace_object',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=self.objects_client,
|
||||
namespace=obj['namespace']['namespace'],
|
||||
object_name=obj['object']['name'])
|
||||
|
||||
def test_create_object(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create objects seperately.
|
||||
pass
|
||||
|
||||
|
||||
class PropertiesProjectAdminTests(rbac_base.MetadefV2RbacPropertiesTest,
|
||||
rbac_base.MetadefV2RbacPropertiesTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_property(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create properties separately.
|
||||
pass
|
||||
|
||||
def test_get_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
# Get all metadef properties with admin role of 'project'
|
||||
for prop in ns_properties:
|
||||
resp = self.do_request(
|
||||
'show_namespace_properties',
|
||||
expected_status=200,
|
||||
client=self.properties_client,
|
||||
namespace=prop['namespace']['namespace'],
|
||||
property_name=prop['property']['name'])
|
||||
self.assertEqual(prop['property'], resp)
|
||||
|
||||
def test_list_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
# list all metadef properties with admin role of 'project'
|
||||
for prop in ns_properties:
|
||||
self.assertPropertyList(prop, self.properties_client)
|
||||
|
||||
def test_update_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
# update all metadef properties with admin role of 'project'
|
||||
for prop in ns_properties:
|
||||
resp = self.do_request(
|
||||
'update_namespace_properties',
|
||||
expected_status=200,
|
||||
namespace=prop['namespace']['namespace'],
|
||||
client=self.properties_client,
|
||||
title="UPDATE_Property",
|
||||
property_name=prop['property']['name'],
|
||||
name=prop['property']['name'],
|
||||
type="string")
|
||||
self.assertNotEqual(prop['property']['title'],
|
||||
resp['title'])
|
||||
|
||||
def test_delete_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
# delete all metadef properties with admin role of 'project'
|
||||
for prop in ns_properties:
|
||||
self.do_request('delete_namespace_property',
|
||||
expected_status=204,
|
||||
namespace=prop['namespace']['namespace'],
|
||||
property_name=prop['property']['name'],
|
||||
client=self.properties_client)
|
||||
|
||||
# Verify the property is deleted successfully
|
||||
self.do_request('show_namespace_properties',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=self.properties_client,
|
||||
namespace=prop['namespace']['namespace'],
|
||||
property_name=prop['property']['name'])
|
||||
|
||||
|
||||
class TagsProjectAdminTests(rbac_base.MetadefV2RbacTagsTest,
|
||||
rbac_base.MetadefV2RbacTagsTemplate):
|
||||
|
||||
credentials = ['project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_tag(self):
|
||||
# As this is been covered in other tests for admin role,
|
||||
# skipping to test only create properties separately.
|
||||
pass
|
||||
|
||||
def test_get_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
# Get all metadef tags with admin role of 'project'
|
||||
for tag in ns_tags:
|
||||
resp = self.do_request(
|
||||
'show_namespace_tag',
|
||||
expected_status=200,
|
||||
client=self.tags_client,
|
||||
namespace=tag['namespace']['namespace'],
|
||||
tag_name=tag['tag']['name'])
|
||||
self.assertEqual(tag['tag']['name'], resp['name'])
|
||||
|
||||
def test_list_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
# list all metadef tags with admin role of 'project'
|
||||
for tag in ns_tags:
|
||||
self.assertTagsList(tag, self.tags_client)
|
||||
|
||||
def test_update_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
# update all metadef tags with admin role of 'project'
|
||||
for tag in ns_tags:
|
||||
resp = self.do_request(
|
||||
'update_namespace_tag',
|
||||
expected_status=200,
|
||||
namespace=tag['namespace']['namespace'],
|
||||
client=self.tags_client,
|
||||
tag_name=tag['tag']['name'],
|
||||
name=data_utils.arbitrary_string(base_text="updated-name"))
|
||||
self.assertNotEqual(tag['tag']['name'], resp['name'])
|
||||
|
||||
def test_delete_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
def assertDeleteTags(tag, client, multiple_tags=False):
|
||||
namespace = tag['namespace']['namespace']
|
||||
if multiple_tags:
|
||||
self.do_request('delete_namespace_tags',
|
||||
expected_status=204,
|
||||
namespace=namespace,
|
||||
client=client)
|
||||
# Verify the tags are deleted successfully
|
||||
resp = self.do_request('list_namespace_tags',
|
||||
client=client,
|
||||
namespace=namespace)
|
||||
self.assertEqual(0, len(resp['tags']))
|
||||
else:
|
||||
tag_name = tag['tag']['name']
|
||||
self.do_request('delete_namespace_tag',
|
||||
expected_status=204,
|
||||
namespace=namespace,
|
||||
tag_name=tag_name,
|
||||
client=client)
|
||||
|
||||
# Verify the tag is deleted successfully
|
||||
self.do_request('show_namespace_tag',
|
||||
expected_status=exceptions.NotFound,
|
||||
client=client,
|
||||
namespace=namespace,
|
||||
tag_name=tag_name)
|
||||
|
||||
# delete all metadef tags with admin role of 'project'
|
||||
for tag in ns_tags:
|
||||
assertDeleteTags(tag, self.tags_client)
|
||||
|
||||
# Create multiple tags
|
||||
ns_multiple_tags = self.create_tags(namespaces, multiple_tags=True)
|
||||
# delete all metadef multiple tags with admin role of 'project'
|
||||
for tags in ns_multiple_tags:
|
||||
assertDeleteTags(tags, self.tags_client, multiple_tags=True)
|
||||
|
@@ -17,13 +17,13 @@ from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions
|
||||
|
||||
from glance_tempest_plugin.tests.rbac.v2.base import ImageV2RbacImageTest
|
||||
from glance_tempest_plugin.tests.rbac.v2.base import ImageV2RbacTemplate
|
||||
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class ProjectMemberTests(ImageV2RbacImageTest, ImageV2RbacTemplate):
|
||||
class ImagesProjectMemberTests(rbac_base.ImageV2RbacImageTest,
|
||||
rbac_base.ImageV2RbacTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_admin', 'system_admin',
|
||||
'project_alt_admin']
|
||||
@@ -730,3 +730,557 @@ class ProjectMemberTests(ImageV2RbacImageTest, ImageV2RbacTemplate):
|
||||
self.do_request('reactivate_image',
|
||||
expected_status=exceptions.Forbidden,
|
||||
image_id=image['id'])
|
||||
|
||||
|
||||
class NamespacesProjectMemberTests(rbac_base.MetadefV2RbacNamespaceTest,
|
||||
rbac_base.MetadefV2RbacNamespaceTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_get_namespace(self):
|
||||
|
||||
def assertGetNamespace(actual_ns, owner, client):
|
||||
expected_status = 200
|
||||
if (actual_ns['visibility'] == 'private' and
|
||||
actual_ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('show_namespace',
|
||||
expected_status=expected_status,
|
||||
client=client,
|
||||
namespace=actual_ns['namespace'])
|
||||
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# Get namespace - member role from 'project' can access all
|
||||
# namespaces of it's own & only public namespace of 'alt_project'
|
||||
for actual_ns in actual_namespaces:
|
||||
assertGetNamespace(actual_ns, self.project_id,
|
||||
self.namespace_client)
|
||||
|
||||
# Get namespace - member role from 'alt_project' can access all
|
||||
# namespaces of it's own & only public namespace of 'project'
|
||||
for actual_ns in actual_namespaces:
|
||||
assertGetNamespace(actual_ns, self.alt_project_id,
|
||||
self.alt_namespace_client)
|
||||
|
||||
def test_list_namespaces(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
# List namespace - member role from 'project' can access all
|
||||
# namespaces of it's own & only public namespace of 'alt_project'
|
||||
resp = self.do_request('list_namespaces',
|
||||
client=self.namespace_client,
|
||||
expected_status=200)
|
||||
self.assertListNamespaces(actual_namespaces, resp, self.project_id)
|
||||
|
||||
# List namespace - member role from 'alt_project' can access all
|
||||
# namespaces of it's own & only public namespace of 'project'
|
||||
resp = self.do_request('list_namespaces',
|
||||
client=self.alt_namespace_client,
|
||||
expected_status=200)
|
||||
self.assertListNamespaces(actual_namespaces, resp, self.alt_project_id)
|
||||
|
||||
def test_update_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
def assertUpdateNamespace(actual_ns, owner, client):
|
||||
expected_status = exceptions.Forbidden
|
||||
if not (actual_ns['visibility'] == 'public' or
|
||||
actual_ns['owner'] == owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('update_namespace',
|
||||
expected_status=expected_status,
|
||||
client=client,
|
||||
description=data_utils.arbitrary_string(),
|
||||
namespace=actual_ns['namespace'])
|
||||
|
||||
# Check member role of 'project' is forbidden to update namespace
|
||||
for actual_ns in actual_namespaces:
|
||||
assertUpdateNamespace(actual_ns, self.project_id,
|
||||
self.namespace_client)
|
||||
|
||||
# Check member role of 'alt_project' is forbidden to update namespace
|
||||
for actual_ns in actual_namespaces:
|
||||
assertUpdateNamespace(actual_ns, self.alt_project_id,
|
||||
self.alt_namespace_client)
|
||||
|
||||
def test_create_namespace(self):
|
||||
# Check non-admin role of 'project' not allowed to create namespace
|
||||
self.do_request('create_namespace',
|
||||
expected_status=exceptions.Forbidden,
|
||||
client=self.namespace_client,
|
||||
namespace=data_utils.arbitrary_string())
|
||||
|
||||
# Check non-admin role of 'alt_project' not allowed to create namespace
|
||||
self.do_request('create_namespace',
|
||||
expected_status=exceptions.Forbidden,
|
||||
client=self.alt_namespace_client,
|
||||
namespace=data_utils.arbitrary_string())
|
||||
|
||||
def test_delete_namespace(self):
|
||||
actual_namespaces = self.create_namespaces()
|
||||
|
||||
def assertDeleteNamespace(actual_ns, owner, client):
|
||||
expected_status = exceptions.Forbidden
|
||||
if not (actual_ns['visibility'] == 'public' or
|
||||
actual_ns['owner'] == owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('delete_namespace',
|
||||
expected_status=expected_status,
|
||||
client=client,
|
||||
namespace=actual_ns['namespace'])
|
||||
|
||||
# Check member role of 'project' is forbidden to delete namespace
|
||||
for actual_ns in actual_namespaces:
|
||||
assertDeleteNamespace(actual_ns, self.project_id,
|
||||
self.namespace_client)
|
||||
|
||||
# Check member role of 'alt_project' is forbidden to delete namespace
|
||||
for actual_ns in actual_namespaces:
|
||||
assertDeleteNamespace(actual_ns, self.alt_project_id,
|
||||
self.alt_namespace_client)
|
||||
|
||||
# Verify the namespaces are not deleted
|
||||
for actual_ns in actual_namespaces:
|
||||
self.do_request('show_namespace',
|
||||
expected_status=200,
|
||||
client=self.admin_namespace_client,
|
||||
namespace=actual_ns['namespace'])
|
||||
|
||||
|
||||
class RSTypesProjectMemberTests(rbac_base.MetadefV2RbacResourceTypeTest,
|
||||
rbac_base.MetadefV2RbacResourceTypeTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member', 'project_admin',
|
||||
'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_resource_type(self):
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
def assertRSTypeCreate(namespace, owner, client):
|
||||
rs_type_name = "rs_type_of_%s" % (namespace['namespace'])
|
||||
expected_status = exceptions.Forbidden
|
||||
if (namespace['visibility'] != 'public' and
|
||||
namespace['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('create_resource_type_association',
|
||||
expected_status=expected_status,
|
||||
namespace_id=namespace['namespace'],
|
||||
name=rs_type_name,
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' forbidden to
|
||||
# create resource types
|
||||
for namespace in namespaces:
|
||||
assertRSTypeCreate(namespace, self.project_id,
|
||||
self.resource_types_client)
|
||||
|
||||
def test_get_resource_type(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
def assertRSTypeGet(actual_rs_type, client, owner):
|
||||
ns = actual_rs_type['namespace']
|
||||
expected_status = 200
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('list_resource_type_association',
|
||||
expected_status=expected_status,
|
||||
namespace_id=ns['namespace'],
|
||||
client=client)
|
||||
|
||||
# Get resource type - member role from 'project' can access all
|
||||
# resource types of it's own & only resource types having public
|
||||
# namespace of 'alt_project'
|
||||
for rs_type in ns_rs_types:
|
||||
assertRSTypeGet(rs_type, self.resource_types_client,
|
||||
self.project_id)
|
||||
|
||||
def test_list_resource_types(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
# list resource types - with member role of 'project'
|
||||
resp = self.do_request('list_resource_types',
|
||||
expected_status=200,
|
||||
client=self.resource_types_client)
|
||||
|
||||
# Verify that member role of 'project' will be able to view available
|
||||
# resource types
|
||||
self.assertRSTypeList(ns_rs_types, resp)
|
||||
|
||||
# list resource types - with member role of 'alt_project'
|
||||
resp = self.do_request('list_resource_types',
|
||||
expected_status=200,
|
||||
client=self.resource_types_client)
|
||||
|
||||
def test_delete_resource_type(self):
|
||||
ns_rs_types = self.create_resource_types()
|
||||
|
||||
def assertRSTypeDelete(actual_rs_type, client, owner):
|
||||
ns = actual_rs_type['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request(
|
||||
'delete_resource_type_association',
|
||||
expected_status=expected_status,
|
||||
namespace_id=ns['namespace'],
|
||||
resource_name=actual_rs_type['resource_type']['name'],
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete resource types
|
||||
for rs_type in ns_rs_types:
|
||||
assertRSTypeDelete(rs_type, self.resource_types_client,
|
||||
self.project_id)
|
||||
|
||||
|
||||
class ObjectsProjectMemberTests(rbac_base.MetadefV2RbacObjectsTest,
|
||||
rbac_base.MetadefV2RbacObjectsTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member', 'project_admin',
|
||||
'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_object(self):
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
def assertCreateObjects(namespace, owner, client):
|
||||
object_name = "object_of_%s" % (namespace['namespace'])
|
||||
expected_status = exceptions.Forbidden
|
||||
if (namespace['visibility'] == 'private' and
|
||||
namespace['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('create_namespace_object',
|
||||
expected_status=expected_status,
|
||||
namespace=namespace['namespace'],
|
||||
name=object_name,
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' forbidden to
|
||||
# create objects
|
||||
for namespace in namespaces:
|
||||
assertCreateObjects(namespace, self.project_id,
|
||||
self.objects_client)
|
||||
|
||||
def test_get_object(self):
|
||||
|
||||
def assertObjectGet(actual_obj, owner, client):
|
||||
ns = actual_obj['namespace']
|
||||
expected_status = 200
|
||||
if (ns['visibility'] == 'private' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('show_namespace_object',
|
||||
expected_status=expected_status,
|
||||
namespace=actual_obj['namespace']['namespace'],
|
||||
object_name=actual_obj['object']['name'],
|
||||
client=client)
|
||||
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# Get object - member role from 'project' can access all
|
||||
# objects of it's own & only objects having public namespace of
|
||||
# 'alt_project'
|
||||
for obj in ns_objects:
|
||||
assertObjectGet(obj, self.project_id, self.objects_client)
|
||||
|
||||
def test_list_objects(self):
|
||||
ns_objects = self.create_objects()
|
||||
|
||||
# list objects - member role from 'project' can access all
|
||||
# objects of it's own & only objects having public namespace of
|
||||
# 'alt_project'
|
||||
for obj in ns_objects:
|
||||
self.assertObjectsList(obj, self.objects_client, self.project_id)
|
||||
|
||||
def test_update_object(self):
|
||||
|
||||
def assertObjectUpdate(actual_object, owner, client):
|
||||
ns = actual_object['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] == 'private' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('update_namespace_object',
|
||||
expected_status=expected_status,
|
||||
name=actual_object['object']['name'],
|
||||
description=data_utils.arbitrary_string(),
|
||||
namespace=actual_object['namespace']['namespace'],
|
||||
object_name=actual_object['object']['name'],
|
||||
client=client)
|
||||
|
||||
ns_objects = self.create_objects()
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# update objects
|
||||
for obj in ns_objects:
|
||||
assertObjectUpdate(obj, self.project_id, self.objects_client)
|
||||
|
||||
def test_delete_object(self):
|
||||
|
||||
def assertObjectDelete(actual_obj, owner, client):
|
||||
ns = actual_obj['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] == 'private' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('delete_namespace_object',
|
||||
expected_status=expected_status,
|
||||
namespace=actual_obj['namespace']['namespace'],
|
||||
object_name=actual_obj['object']['name'],
|
||||
client=client)
|
||||
|
||||
ns_objects = self.create_objects()
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete objects
|
||||
for obj in ns_objects:
|
||||
assertObjectDelete(obj, self.project_id, self.objects_client)
|
||||
|
||||
|
||||
class PropertiesProjectMemberTests(rbac_base.MetadefV2RbacPropertiesTest,
|
||||
rbac_base.MetadefV2RbacPropertiesTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_property(self):
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
def assertPropertyCreate(namespace, client, owner=None):
|
||||
property_name = "prop_of_%s" % (namespace['namespace'])
|
||||
expected_status = exceptions.Forbidden
|
||||
if not (namespace['visibility'] == 'public' or
|
||||
namespace['owner'] == owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('create_namespace_property',
|
||||
expected_status=expected_status,
|
||||
namespace=namespace['namespace'],
|
||||
title="property",
|
||||
type='integer',
|
||||
name=property_name,
|
||||
client=client)
|
||||
# Make sure non admin role of 'project' forbidden to
|
||||
# create properties
|
||||
for namespace in namespaces:
|
||||
assertPropertyCreate(namespace, self.properties_client,
|
||||
self.project_id)
|
||||
|
||||
def test_get_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
def assertPropertyGet(actual_prop, client, owner=None):
|
||||
ns = actual_prop['namespace']
|
||||
expected_status = 200
|
||||
if (ns['visibility'] != 'public' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('show_namespace_properties',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
property_name=actual_prop['property']['name'],
|
||||
client=client)
|
||||
|
||||
# Get property - member role from 'project' can access all
|
||||
# properties of it's own & only propertys having public namespace of
|
||||
# 'alt_project'
|
||||
for prop in ns_properties:
|
||||
assertPropertyGet(prop, self.properties_client, self.project_id)
|
||||
|
||||
def test_list_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
# list properties - member role from 'project' can access all
|
||||
# properties of it's own & only propertys having public namespace of
|
||||
# 'alt_project'
|
||||
for prop in ns_properties:
|
||||
self.assertPropertyList(prop, self.properties_client,
|
||||
self.project_id)
|
||||
|
||||
def test_update_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
def assertPropertyUpdate(actual_prop, client, owner=None):
|
||||
ns = actual_prop['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('update_namespace_properties',
|
||||
expected_status=expected_status,
|
||||
name=actual_prop['property']['name'],
|
||||
description=data_utils.arbitrary_string(),
|
||||
namespace=ns['namespace'],
|
||||
property_name=actual_prop['property']['name'],
|
||||
title="UPDATE_Property",
|
||||
type="string",
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# update properties
|
||||
for prop in ns_properties:
|
||||
assertPropertyUpdate(prop, self.properties_client,
|
||||
self.project_id)
|
||||
|
||||
def test_delete_properties(self):
|
||||
ns_properties = self.create_properties()
|
||||
|
||||
def assertPropertyDelete(actual_prop, client, owner=None):
|
||||
ns = actual_prop['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and
|
||||
ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('delete_namespace_property',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
property_name=actual_prop['property']['name'],
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete properties
|
||||
for prop in ns_properties:
|
||||
assertPropertyDelete(prop, self.properties_client,
|
||||
self.project_id)
|
||||
|
||||
|
||||
class TagsProjectMemberTests(rbac_base.MetadefV2RbacTagsTest,
|
||||
rbac_base.MetadefV2RbacTagsTemplate):
|
||||
|
||||
credentials = ['project_member', 'project_alt_member',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
def test_create_tag(self):
|
||||
namespaces = self.create_namespaces()
|
||||
|
||||
def assertTagsCreate(namespace, client, owner, multiple_tags=False):
|
||||
expected_status = exceptions.Forbidden
|
||||
if (namespace['visibility'] != 'public' and
|
||||
namespace['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
if multiple_tags:
|
||||
multiple_tags = [{"name": "tag1"}, {"name": "tag2"},
|
||||
{"name": "tag3"}]
|
||||
self.do_request('create_namespace_tags',
|
||||
expected_status=expected_status,
|
||||
namespace=namespace['namespace'],
|
||||
tags=multiple_tags,
|
||||
client=client)
|
||||
else:
|
||||
tag_name = "tag_of_%s" % (namespace['namespace'])
|
||||
self.do_request('create_namespace_tag',
|
||||
expected_status=expected_status,
|
||||
namespace=namespace['namespace'],
|
||||
tag_name=tag_name,
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' forbidden to
|
||||
# create tags
|
||||
for namespace in namespaces:
|
||||
assertTagsCreate(namespace, self.tags_client, self.project_id)
|
||||
|
||||
# Create Multiple Tags
|
||||
assertTagsCreate(namespace, self.tags_client, self.project_id,
|
||||
multiple_tags=True)
|
||||
|
||||
def test_get_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
def assertTagGet(actual_tag, client, owner=None):
|
||||
ns = actual_tag['namespace']
|
||||
expected_status = 200
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('show_namespace_tag',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
tag_name=actual_tag['tag']['name'],
|
||||
client=client)
|
||||
|
||||
# Get tag - member role from 'project' can access all
|
||||
# tags of it's own & only tags having public namespace of
|
||||
# 'alt_project'
|
||||
for tag in ns_tags:
|
||||
assertTagGet(tag, self.tags_client, self.project_id)
|
||||
|
||||
def test_list_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
# list tags - member role from 'project' can access all
|
||||
# tags of it's own & only tags having public namespace of
|
||||
# 'alt_project'
|
||||
for tag in ns_tags:
|
||||
self.assertTagsList(tag, self.tags_client, self.project_id)
|
||||
|
||||
def test_update_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
def assertTagUpdate(tag, client, owner):
|
||||
ns = tag['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
self.do_request('update_namespace_tag',
|
||||
expected_status=expected_status,
|
||||
name=data_utils.arbitrary_string(),
|
||||
namespace=tag['namespace']['namespace'],
|
||||
tag_name=tag['tag']['name'],
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# update tags
|
||||
for tag in ns_tags:
|
||||
assertTagUpdate(tag, self.tags_client, self.project_id)
|
||||
|
||||
def test_delete_tags(self):
|
||||
namespaces = self.create_namespaces()
|
||||
ns_tags = self.create_tags(namespaces)
|
||||
|
||||
def assertTagsDelete(actual_tag, client, owner, multiple_tags=False):
|
||||
ns = tag['namespace']
|
||||
expected_status = exceptions.Forbidden
|
||||
if (ns['visibility'] != 'public' and ns['owner'] != owner):
|
||||
expected_status = exceptions.NotFound
|
||||
|
||||
if multiple_tags:
|
||||
self.do_request('delete_namespace_tags',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
client=client)
|
||||
else:
|
||||
self.do_request('delete_namespace_tag',
|
||||
expected_status=expected_status,
|
||||
namespace=ns['namespace'],
|
||||
tag_name=actual_tag['tag']['name'],
|
||||
client=client)
|
||||
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete tags
|
||||
for tag in ns_tags:
|
||||
assertTagsDelete(tag, self.tags_client, self.project_id)
|
||||
|
||||
# Create Multiple Tags
|
||||
ns_multiple_tags = self.create_tags(namespaces, multiple_tags=True)
|
||||
# Make sure non admin role of 'project' not allowed to
|
||||
# delete multiple tags
|
||||
for tags in ns_multiple_tags:
|
||||
assertTagsDelete(tags, self.tags_client, self.project_id,
|
||||
multiple_tags=True)
|
||||
|
@@ -22,7 +22,8 @@ from glance_tempest_plugin.tests.rbac.v2 import test_project_members_tests
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class ProjectReaderTests(test_project_members_tests.ProjectMemberTests):
|
||||
class ImagesProjectReaderTests(
|
||||
test_project_members_tests.ImagesProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_admin', 'system_admin',
|
||||
'project_alt_admin']
|
||||
@@ -591,3 +592,37 @@ class ProjectReaderTests(test_project_members_tests.ProjectMemberTests):
|
||||
self.do_request('reactivate_image',
|
||||
expected_status=exceptions.Forbidden,
|
||||
image_id=image['id'])
|
||||
|
||||
|
||||
class NamespacesProjectReaderTests(
|
||||
test_project_members_tests.NamespacesProjectMemberTests):
|
||||
credentials = ['project_reader', 'project_alt_reader',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
|
||||
class RSTypesProjectReaderTests(
|
||||
test_project_members_tests.RSTypesProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_alt_reader', 'project_admin',
|
||||
'project_alt_admin', 'primary']
|
||||
|
||||
|
||||
class ObjectsProjectReaderTests(
|
||||
test_project_members_tests.ObjectsProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_alt_reader', 'project_admin',
|
||||
'project_alt_admin', 'primary']
|
||||
|
||||
|
||||
class PropertiesProjectReaderTests(
|
||||
test_project_members_tests.PropertiesProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_alt_reader',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
||||
|
||||
class TagsProjectReaderTests(
|
||||
test_project_members_tests.TagsProjectMemberTests):
|
||||
|
||||
credentials = ['project_reader', 'project_alt_reader',
|
||||
'project_admin', 'project_alt_admin', 'primary']
|
||||
|
Reference in New Issue
Block a user