Merge "Add srbac metadef tests"

This commit is contained in:
Zuul
2025-07-03 17:34:26 +00:00
committed by Gerrit Code Review
6 changed files with 1061 additions and 84 deletions

View File

@@ -9,6 +9,7 @@
# 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.api.image import base
@@ -286,6 +287,7 @@ class MetadefV2RbacNamespaceTest(RbacMetadefBase):
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.namespaces_client = cls.persona.namespaces_client
cls.namespace_client = cls.persona.namespaces_client
cls.alt_namespace_client = cls.alt_persona.namespaces_client
@@ -302,6 +304,40 @@ class MetadefV2RbacNamespaceTest(RbacMetadefBase):
for ns in actual:
self.assertIn(ns['namespace'], expected_ns)
def assertGetNamespace(self, 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'])
def assertUpdateNamespace(self, 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'])
def assertDeleteNamespace(self, 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'])
class MetadefV2RbacNamespaceTemplate(metaclass=abc.ABCMeta):
@@ -350,24 +386,40 @@ class MetadefV2RbacResourceTypeTest(RbacMetadefBase):
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()
def create_resource_types(self, namespace=None, owner=None, client=None,
is_admin=True):
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)
if is_admin:
# Create namespace for two different projects
namespaces = self.create_namespaces()
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)
else:
rs_type_name = "rs_type_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_resource_type_association',
expected_status=expected_status,
namespace_id=namespace['namespace'],
name=rs_type_name,
client=client)
return namespace_resource_types
@@ -378,6 +430,30 @@ class MetadefV2RbacResourceTypeTest(RbacMetadefBase):
self.assertIn(rs_type['resource_type']['name'],
actual_rs_types)
def assertRSTypeGet(self, 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)
def assertRSTypeDelete(self, 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)
class MetadefV2RbacResourceTypeTemplate(metaclass=abc.ABCMeta):
@@ -422,23 +498,37 @@ class MetadefV2RbacObjectsTest(RbacMetadefBase):
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
def create_objects(self, namespace=None, owner=None, client=None,
is_admin=True):
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)
if is_admin:
# Create namespace for two different projects
namespaces = self.create_namespaces()
for ns in namespaces:
alt_client = None
if ns['namespace'].startswith(self.alt_project_id):
alt_client = \
self.os_project_alt_admin.namespace_objects_client
client = alt_client
if alt_client is None:
client = self.os_project_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)
else:
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)
return namespace_objects
def assertObjectsList(self, actual_obj, client, owner=None):
@@ -465,6 +555,47 @@ class MetadefV2RbacObjectsTest(RbacMetadefBase):
self.assertIn(actual_obj['object']['name'],
resp['objects'][0]['name'])
def assertObjectGet(self, 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)
def assertObjectUpdate(self, 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)
def assertObjectDelete(self, 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)
class MetadefV2RbacObjectsTemplate(metaclass=abc.ABCMeta):
@@ -513,28 +644,39 @@ class MetadefV2RbacPropertiesTest(RbacMetadefBase):
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()
def create_properties(self, namespace=None, owner=None, client=None,
is_admin=True):
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)
if is_admin:
# Create namespace for two different projects
namespaces = self.create_namespaces()
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)
else:
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)
return namespace_properties
def assertPropertyList(self, actual_prop, client, owner=None):
@@ -560,6 +702,43 @@ class MetadefV2RbacPropertiesTest(RbacMetadefBase):
self.assertEqual(actual_prop['property']['name'],
[*resp['properties']][0])
def assertPropertyGet(self, 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)
def assertPropertyUpdate(self, 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)
def assertPropertyDelete(self, 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)
class MetadefV2RbacPropertiesTemplate(metaclass=abc.ABCMeta):
@@ -608,47 +787,71 @@ class MetadefV2RbacTagsTest(RbacMetadefBase):
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):
def create_tags(self, namespace=None, client=None, owner=None,
multiple_tags=False, is_admin=True):
namespace_tags = []
if is_admin:
# Create namespace for two different projects
if not multiple_tags:
for ns in namespace:
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)
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(
tag = {'namespace': ns, 'tag': namespace_tag}
namespace_tags.append(tag)
else:
tags = [{"name": "tag1"}, {"name": "tag2"}, {"name": "tag3"}]
for ns in namespace:
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
namespace_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)
multiple_tags = {'namespace': ns,
'tags': namespace_multiple_tags}
namespace_tags.append(multiple_tags)
tag = {'namespace': ns, 'tag': namespace_tag}
namespace_tags.append(tag)
else:
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)
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):
if (ns['visibility'] != 'public' and ns['owner'] != owner):
self.do_request('list_namespace_tags',
expected_status=exceptions.NotFound,
client=client,
@@ -668,6 +871,77 @@ class MetadefV2RbacTagsTest(RbacMetadefBase):
self.assertEqual(actual_tag['tag']['name'],
resp['tags'][0]['name'])
def assertTagGet(self, 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)
def assertTagUpdate(self, 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)
def assertDeleteTags(self, tag, client, owner=None, multiple_tags=False,
is_admin=True):
if is_admin:
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)
else:
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=tag['tag']['name'],
client=client)
class MetadefV2RbacTagsTemplate(metaclass=abc.ABCMeta):

View File

@@ -0,0 +1,138 @@
# 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.
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 ProjectAdminTests(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.namespaces_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.namespaces_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.namespaces_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.namespaces_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(rbac_base.MetadefV2RbacNamespaceTest,
rbac_base.MetadefV2RbacNamespaceTemplate):
credentials = ['project_member', 'project_alt_member',
'project_admin', 'project_alt_admin', 'primary']
def test_get_namespace(self):
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:
self.assertGetNamespace(actual_ns, self.project_id,
self.namespaces_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.namespaces_client,
expected_status=200)
self.assertListNamespaces(actual_namespaces, resp, self.project_id)
def test_update_namespace(self):
actual_namespaces = self.create_namespaces()
# Check member role of 'project' is forbidden to update namespace
for actual_ns in actual_namespaces:
self.assertUpdateNamespace(actual_ns, self.project_id,
self.namespaces_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.namespaces_client,
namespace=data_utils.arbitrary_string())
def test_delete_namespace(self):
actual_namespaces = self.create_namespaces()
# Check member role of 'project' is forbidden to delete namespace
for actual_ns in actual_namespaces:
self.assertDeleteNamespace(actual_ns, self.project_id,
self.namespaces_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']

View File

@@ -0,0 +1,140 @@
# 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.
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 ProjectAdminTests(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 ProjectMemberTests(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()
# Make sure non admin role of 'project' forbidden to
# create objects
for namespace in namespaces:
self.create_objects(namespace, self.project_id,
self.objects_client, is_admin=False)
def test_get_object(self):
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:
self.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):
ns_objects = self.create_objects()
# Make sure non admin role of 'project' not allowed to
# update objects
for obj in ns_objects:
self.assertObjectUpdate(obj, self.project_id, self.objects_client)
def test_delete_object(self):
ns_objects = self.create_objects()
# Make sure non admin role of 'project' not allowed to
# delete objects
for obj in ns_objects:
self.assertObjectDelete(obj, self.project_id, self.objects_client)
class ProjectReaderTests(ProjectMemberTests):
credentials = ['project_reader', 'project_alt_reader', 'project_admin',
'project_alt_admin', 'primary']

View File

@@ -0,0 +1,143 @@
# 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.
from tempest.lib import exceptions
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
class ProjectAdminTests(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 ProjectMemberTests(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()
# Make sure non admin role of 'project' forbidden to
# create properties
for namespace in namespaces:
self.create_properties(namespace, self.project_id,
self.properties_client, is_admin=False)
def test_get_properties(self):
ns_properties = self.create_properties()
# 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:
self.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()
# Make sure non admin role of 'project' not allowed to
# update properties
for prop in ns_properties:
self.assertPropertyUpdate(prop, self.properties_client,
self.project_id)
def test_delete_properties(self):
ns_properties = self.create_properties()
# Make sure non admin role of 'project' not allowed to
# delete properties
for prop in ns_properties:
self.assertPropertyDelete(prop, self.properties_client,
self.project_id)
class ProjectReaderTests(ProjectMemberTests):
credentials = ['project_reader', 'project_alt_reader',
'project_admin', 'project_alt_admin', 'primary']

View File

@@ -0,0 +1,129 @@
# 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.
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
class ProjectAdminTests(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 ProjectMemberTests(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()
# Make sure non admin role of 'project' forbidden to
# create resource types
for namespace in namespaces:
self.create_resource_types(namespace, self.project_id,
self.resource_types_client,
is_admin=False)
def test_get_resource_type(self):
ns_rs_types = self.create_resource_types()
# 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:
self.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()
# Make sure non admin role of 'project' not allowed to
# delete resource types
for rs_type in ns_rs_types:
self.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']

View File

@@ -0,0 +1,153 @@
# 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.
from tempest.lib.common.utils import data_utils
from glance_tempest_plugin.tests.rbac.v2 import base as rbac_base
class ProjectAdminTests(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)
# delete all metadef tags with admin role of 'project'
for tag in ns_tags:
self.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:
self.assertDeleteTags(tags, self.tags_client, multiple_tags=True)
class ProjectMemberTests(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()
# Make sure non admin role of 'project' forbidden to
# create tags
for namespace in namespaces:
self.create_tags(namespace, self.tags_client, self.project_id,
is_admin=False)
# Create Multiple Tags
self.create_tags(namespace, self.tags_client, self.project_id,
multiple_tags=True, is_admin=False)
def test_get_tags(self):
namespaces = self.create_namespaces()
ns_tags = self.create_tags(namespaces)
# 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:
self.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)
# Make sure non admin role of 'project' not allowed to
# update tags
for tag in ns_tags:
self.assertTagUpdate(tag, self.tags_client, self.project_id)
def test_delete_tags(self):
namespaces = self.create_namespaces()
ns_tags = self.create_tags(namespaces)
# Make sure non admin role of 'project' not allowed to
# delete tags
for tag in ns_tags:
self.assertDeleteTags(tag, self.tags_client, self.project_id,
is_admin=False)
# 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:
self.assertDeleteTags(tags, self.tags_client, self.project_id,
multiple_tags=True, is_admin=False)
class ProjectReaderTests(ProjectMemberTests):
credentials = ['project_reader', 'project_alt_reader',
'project_admin', 'project_alt_admin', 'primary']