Merge "Revert project-specific APIs for servers"

This commit is contained in:
Zuul
2022-02-24 18:17:47 +00:00
committed by Gerrit Code Review
8 changed files with 539 additions and 643 deletions
+5 -2
View File
@@ -56,6 +56,7 @@ PROJECT_MEMBER = 'rule:project_member_api'
PROJECT_READER = 'rule:project_reader_api'
PROJECT_MEMBER_OR_SYSTEM_ADMIN = 'rule:system_admin_or_owner'
PROJECT_READER_OR_SYSTEM_READER = 'rule:system_or_project_reader'
ADMIN = 'rule:context_is_admin'
# NOTE(gmann): Below is the mapping of new roles and scope_types
# with legacy roles::
@@ -88,7 +89,8 @@ rules = [
policy.RuleDefault(
"context_is_admin",
"role:admin",
"Decides what is required for the 'is_admin:True' check to succeed."),
"Decides what is required for the 'is_admin:True' check to succeed.",
deprecated_rule=DEPRECATED_ADMIN_POLICY),
policy.RuleDefault(
"admin_or_owner",
"is_admin:True or project_id:%(project_id)s",
@@ -126,7 +128,8 @@ rules = [
policy.RuleDefault(
"project_reader_api",
"role:reader and project_id:%(project_id)s",
"Default rule for Project level read only APIs."),
"Default rule for Project level read only APIs.",
deprecated_rule=DEPRECATED_ADMIN_OR_OWNER_POLICY),
policy.RuleDefault(
name="system_admin_or_owner",
check_str="rule:system_admin_api or rule:project_member_api",
+2 -2
View File
@@ -24,7 +24,7 @@ BASE_POLICY_NAME = 'os_compute_api:os-extended-server-attributes'
extended_server_attributes_policies = [
policy.DocumentedRuleDefault(
name=BASE_POLICY_NAME,
check_str=base.SYSTEM_ADMIN,
check_str=base.PROJECT_ADMIN,
description="""Return extended attributes for server.
This rule will control the visibility for a set of servers attributes:
@@ -66,7 +66,7 @@ is therefore deprecated and will be removed in a future release.
'path': '/servers/{server_id}/action (rebuild)'
}
],
scope_types=['system', 'project']
scope_types=['project']
),
]
+4 -4
View File
@@ -37,7 +37,7 @@ flavor_extra_specs_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'create',
check_str=base.SYSTEM_ADMIN,
check_str=base.ADMIN,
description="Create extra specs for a flavor",
operations=[
{
@@ -49,7 +49,7 @@ flavor_extra_specs_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'update',
check_str=base.SYSTEM_ADMIN,
check_str=base.ADMIN,
description="Update an extra spec for a flavor",
operations=[
{
@@ -62,7 +62,7 @@ flavor_extra_specs_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
check_str=base.SYSTEM_ADMIN,
check_str=base.ADMIN,
description="Delete an extra spec for a flavor",
operations=[
{
@@ -75,7 +75,7 @@ flavor_extra_specs_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
check_str=base.PROJECT_READER,
description="List extra specs for a flavor. Starting with "
"microversion 2.47, the flavor used for a server is also returned "
"in the response when showing server details, updating a server or "
+48 -68
View File
@@ -25,7 +25,7 @@ CROSS_CELL_RESIZE = 'compute:servers:resize:cross_cell'
rules = [
policy.DocumentedRuleDefault(
name=SERVERS % 'index',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
check_str=base.PROJECT_READER,
description="List all servers",
operations=[
{
@@ -33,10 +33,10 @@ rules = [
'path': '/servers'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'detail',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
check_str=base.PROJECT_READER,
description="List all servers with detailed information",
operations=[
{
@@ -44,10 +44,10 @@ rules = [
'path': '/servers/detail'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'index:get_all_tenants',
check_str=base.SYSTEM_READER,
check_str=base.PROJECT_ADMIN,
description="List all servers for all projects",
operations=[
{
@@ -55,10 +55,11 @@ rules = [
'path': '/servers'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'detail:get_all_tenants',
check_str=base.SYSTEM_READER,
check_str=base.PROJECT_ADMIN,
description="List all servers with detailed information for "
" all projects",
operations=[
@@ -67,10 +68,10 @@ rules = [
'path': '/servers/detail'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'allow_all_filters',
check_str=base.SYSTEM_READER,
check_str=base.PROJECT_ADMIN,
description="Allow all filters when listing servers",
operations=[
{
@@ -82,10 +83,10 @@ rules = [
'path': '/servers/detail'
}
],
scope_types=['system']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'show',
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
check_str=base.PROJECT_READER,
description="Show a server",
operations=[
{
@@ -93,12 +94,12 @@ rules = [
'path': '/servers/{server_id}'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
# the details in host_status are pretty sensitive, only admins
# should do that by default.
policy.DocumentedRuleDefault(
name=SERVERS % 'show:host_status',
check_str=base.SYSTEM_ADMIN,
check_str=base.PROJECT_ADMIN,
description="""
Show a server with additional host status information.
@@ -129,10 +130,10 @@ API responses which are also controlled by this policy rule, like the
'path': '/servers/{server_id}/action (rebuild)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'show:host_status:unknown-only',
check_str=base.SYSTEM_ADMIN,
check_str=base.PROJECT_ADMIN,
description="""
Show a server with additional host status information, only if host status is
UNKNOWN.
@@ -162,7 +163,7 @@ allow everyone.
'path': '/servers/{server_id}/action (rebuild)'
}
],
scope_types=['system', 'project'],),
scope_types=['project'],),
policy.DocumentedRuleDefault(
name=SERVERS % 'create',
check_str=base.PROJECT_MEMBER,
@@ -176,16 +177,6 @@ allow everyone.
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'create:forced_host',
# TODO(gmann): We need to make it SYSTEM_ADMIN.
# PROJECT_ADMIN is added for now because create server
# policy is project scoped and there is no way to
# pass the project_id in request body for system scoped
# roles so that create server for other project with force host.
# To achieve that, we need to update the create server API to
# accept the project_id for whom the server needs to be created
# and then change the scope of this policy to system-only
# Because that is API change it needs to be done with new
# microversion.
check_str=base.PROJECT_ADMIN,
description="""
Create a server on the specified host and/or node.
@@ -200,20 +191,9 @@ host and/or node by bypassing the scheduler filters unlike the
'path': '/servers'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=REQUESTED_DESTINATION,
# TODO(gmann): We need to make it SYSTEM_ADMIN.
# PROJECT_ADMIN is added for now because create server
# policy is project scoped and there is no way to
# pass the project_id in request body for system scoped
# roles so that create server for other project with requested
# destination.
# To achieve that, we need to update the create server API to
# accept the project_id for whom the server needs to be created
# and then change the scope of this policy to system-only
# Because that is API change it needs to be done with new
# microversion.
check_str=base.PROJECT_ADMIN,
description="""
Create a server on the requested compute service host and/or
@@ -229,7 +209,7 @@ validated by the scheduler filters unlike the
'path': '/servers'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'create:attach_volume',
check_str=base.PROJECT_MEMBER,
@@ -288,7 +268,7 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=NETWORK_ATTACH_EXTERNAL,
check_str=base.PROJECT_ADMIN,
@@ -305,10 +285,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/os-interface'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'delete',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Delete a server",
operations=[
{
@@ -316,10 +296,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'update',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Update a server",
operations=[
{
@@ -327,10 +307,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'confirm_resize',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Confirm a server resize",
operations=[
{
@@ -338,10 +318,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (confirmResize)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'revert_resize',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Revert a server resize",
operations=[
{
@@ -349,10 +329,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (revertResize)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'reboot',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Reboot a server",
operations=[
{
@@ -360,10 +340,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (reboot)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'resize',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Resize a server",
operations=[
{
@@ -371,7 +351,7 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (resize)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=CROSS_CELL_RESIZE,
check_str=base.RULE_NOBODY,
@@ -386,10 +366,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (resize)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'rebuild',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Rebuild a server",
operations=[
{
@@ -397,10 +377,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (rebuild)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'rebuild:trusted_certs',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Rebuild a server with trusted image certificate IDs",
operations=[
{
@@ -408,10 +388,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (rebuild)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'create_image',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Create an image from a server",
operations=[
{
@@ -419,10 +399,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (createImage)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'create_image:allow_volume_backed',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Create an image from a volume backed server",
operations=[
{
@@ -430,10 +410,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (createImage)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'start',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Start a server",
operations=[
{
@@ -441,10 +421,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (os-start)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'stop',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Stop a server",
operations=[
{
@@ -452,10 +432,10 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (os-stop)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
policy.DocumentedRuleDefault(
name=SERVERS % 'trigger_crash_dump',
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
check_str=base.PROJECT_MEMBER,
description="Trigger crash dump in a server",
operations=[
{
@@ -463,7 +443,7 @@ https://bugs.launchpad.net/nova/+bug/1739646 for details.
'path': '/servers/{server_id}/action (trigger_crash_dump)'
}
],
scope_types=['system', 'project']),
scope_types=['project']),
]
+64 -2
View File
@@ -95,14 +95,28 @@ class BasePolicyTest(test.TestCase):
project_id=self.project_id_other,
roles=['reader'])
self.all_contexts = [
self.all_contexts = set([
self.legacy_admin_context, self.system_admin_context,
self.system_member_context, self.system_reader_context,
self.system_foo_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.other_project_member_context,
self.project_foo_context, self.other_project_reader_context
]
])
# All the project contexts for easy access.
self.all_project_contexts = set([
self.legacy_admin_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context,
])
# All the system contexts for easy access.
self.all_system_contexts = set([
self.system_admin_context, self.system_foo_context,
self.system_member_context, self.system_reader_context,
])
if self.without_deprecated_rules:
# To simulate the new world, remove deprecations by overriding
@@ -118,10 +132,58 @@ class BasePolicyTest(test.TestCase):
"role:reader and system_scope:all",
"project_member_api":
"role:member and project_id:%(project_id)s",
"project_reader_api":
"role:reader and project_id:%(project_id)s",
})
self.policy.set_rules(self.rules_without_deprecation,
overwrite=False)
def reduce_set(self, name, new_set):
"""Reduce a named set of contexts in a subclass.
This removes things from a set in a child test class by taking
a new set, but asserts that no *new* contexts are added over
what is defined in the parent.
:param name: The name of a set of contexts on self
(i.e. 'project' for self.project_contexts
:param new_set: The new set of contexts that should be used in
the above set. The new_set is asserted to be a
perfect subset of the existing set
"""
current = getattr(self, '%s_contexts' % name)
errors = ','.join(x.user_id for x in new_set - current)
self.assertEqual('', errors,
'Attempt to reduce set would add %s' % errors)
LOG.info('%s.%s_contexts: removing %s',
self.__class__.__name__,
name,
','.join(x.user_id for x in current - new_set))
setattr(self, '%s_contexts' % name, new_set)
def common_policy_auth(self, authorized_contexts,
rule_name,
func, req, *arg, **kwarg):
"""Check a policy rule against a set of authorized contexts.
This is exactly like common_policy_check, except that it
assumes any contexts not in the authorized set are in the
unauthorized set.
"""
# The unauthorized users are any not in the authorized set.
unauth = list(set(self.all_contexts) - set(authorized_contexts))
# In case a set was passed in, convert to list for stable ordering.
authorized_contexts = list(authorized_contexts)
# Log both sets in the order we will test them to aid debugging of
# fatal=False responses.
LOG.info('Authorized users: %s', list(
x.user_id for x in authorized_contexts))
LOG.info('Unauthorized users: %s', list(x.user_id for x in unauth))
return self.common_policy_check(authorized_contexts, unauth,
rule_name, func, req, *arg, **kwarg)
def common_policy_check(self, authorized_contexts,
unauthorized_contexts, rule_name,
func, req, *arg, **kwarg):
@@ -77,99 +77,74 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
self.stub_out('nova.api.openstack.common.get_flavor',
get_flavor_extra_specs)
# Check that all are able to get flavor extra specs.
self.all_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.system_member_context, self.system_reader_context,
self.system_foo_context,
self.other_project_member_context,
self.other_project_reader_context
]
self.all_unauthorized_contexts = []
# Check that all system scoped are able to get flavor extra specs.
self.all_system_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.system_member_context, self.system_reader_context,
self.system_foo_context,
self.other_project_member_context,
self.other_project_reader_context
]
self.all_system_unauthorized_contexts = []
# In the base/legacy case, all project and system contexts are
# authorized in the "anyone" case.
self.all_authorized_contexts = (self.all_project_contexts |
self.all_system_contexts)
# Check that admin is able to create, update and delete flavor
# extra specs.
self.admin_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
# Check that non-admin is not able to create, update and
# delete flavor extra specs.
self.admin_unauthorized_contexts = [
self.system_member_context, self.system_reader_context,
self.system_foo_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context
]
# In the base/legacy case, all project and system contexts are
# authorized in the case of things that distinguish between
# scopes, since scope checking is disabled.
self.all_system_authorized_contexts = (self.all_project_contexts |
self.all_system_contexts)
self.all_project_authorized_contexts = (self.all_project_contexts |
self.all_system_contexts)
# In the base/legacy case, any admin is an admin.
self.admin_authorized_contexts = set([self.project_admin_context,
self.system_admin_context,
self.legacy_admin_context])
@mock.patch('nova.objects.Flavor.save')
def test_create_flavor_extra_specs_policy(self, mock_save):
body = {'extra_specs': {'hw:numa_nodes': '1'}}
rule_name = policies.POLICY_ROOT % 'create'
self.common_policy_check(self.admin_authorized_contexts,
self.admin_unauthorized_contexts,
rule_name,
self.controller.create,
self.req, '1234',
body=body)
self.common_policy_auth(self.admin_authorized_contexts,
rule_name,
self.controller.create,
self.req, '1234',
body=body)
@mock.patch('nova.objects.Flavor._flavor_extra_specs_del')
@mock.patch('nova.objects.Flavor.save')
def test_delete_flavor_extra_specs_policy(self, mock_save, mock_delete):
rule_name = policies.POLICY_ROOT % 'delete'
self.common_policy_check(self.admin_authorized_contexts,
self.admin_unauthorized_contexts,
rule_name,
self.controller.delete,
self.req, '1234', 'hw:cpu_policy')
self.common_policy_auth(self.admin_authorized_contexts,
rule_name,
self.controller.delete,
self.req, '1234', 'hw:cpu_policy')
@mock.patch('nova.objects.Flavor.save')
def test_update_flavor_extra_specs_policy(self, mock_save):
body = {'hw:cpu_policy': 'shared'}
rule_name = policies.POLICY_ROOT % 'update'
self.common_policy_check(self.admin_authorized_contexts,
self.admin_unauthorized_contexts,
rule_name,
self.controller.update,
self.req, '1234', 'hw:cpu_policy',
body=body)
self.common_policy_auth(self.admin_authorized_contexts,
rule_name,
self.controller.update,
self.req, '1234', 'hw:cpu_policy',
body=body)
def test_show_flavor_extra_specs_policy(self):
rule_name = policies.POLICY_ROOT % 'show'
self.common_policy_check(self.all_authorized_contexts,
self.all_unauthorized_contexts,
rule_name,
self.controller.show,
self.req, '1234',
'hw:cpu_policy')
self.common_policy_auth(self.all_authorized_contexts,
rule_name,
self.controller.show,
self.req, '1234',
'hw:cpu_policy')
def test_index_flavor_extra_specs_policy(self):
rule_name = policies.POLICY_ROOT % 'index'
self.common_policy_check(self.all_authorized_contexts,
self.all_unauthorized_contexts,
rule_name,
self.controller.index,
self.req, '1234')
self.common_policy_auth(self.all_authorized_contexts,
rule_name,
self.controller.index,
self.req, '1234')
def test_flavor_detail_with_extra_specs_policy(self):
fakes.stub_out_flavor_get_all(self)
rule_name = policies.POLICY_ROOT % 'index'
req = fakes.HTTPRequest.blank('', version='2.61')
authorize_res, unauthorize_res = self.common_policy_check(
self.all_authorized_contexts, self.all_unauthorized_contexts,
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_authorized_contexts,
rule_name, self.flavor_ctrl.detail, req,
fatal=False)
for resp in authorize_res:
@@ -181,8 +156,8 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
fakes.stub_out_flavor_get_by_flavor_id(self)
rule_name = policies.POLICY_ROOT % 'index'
req = fakes.HTTPRequest.blank('', version='2.61')
authorize_res, unauthorize_res = self.common_policy_check(
self.all_authorized_contexts, self.all_unauthorized_contexts,
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_authorized_contexts,
rule_name, self.flavor_ctrl.show, req, '1',
fatal=False)
for resp in authorize_res:
@@ -221,9 +196,8 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
"disk": 1,
}
}
authorize_res, unauthorize_res = self.common_policy_check(
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_system_authorized_contexts,
self.all_system_unauthorized_contexts,
rule_name, self.fm_ctrl._create, req, body=body,
fatal=False)
for resp in authorize_res:
@@ -242,9 +216,8 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.61')
authorize_res, unauthorize_res = self.common_policy_check(
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_system_authorized_contexts,
self.all_system_unauthorized_contexts,
rule_name, self.fm_ctrl._update, req, '1',
body={'flavor': {'description': None}},
fatal=False)
@@ -261,8 +234,8 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.47')
rule_name = policies.POLICY_ROOT % 'index'
authorize_res, unauthorize_res = self.common_policy_check(
self.all_authorized_contexts, self.all_unauthorized_contexts,
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_project_authorized_contexts,
rule_name, self.server_ctrl.detail, req,
fatal=False)
for resp in authorize_res:
@@ -280,9 +253,8 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.47')
rule_name = policies.POLICY_ROOT % 'index'
authorize_res, unauthorize_res = self.common_policy_check(
self.all_authorized_contexts,
self.all_unauthorized_contexts,
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_project_authorized_contexts,
rule_name, self.server_ctrl.show, req, 'fake',
fatal=False)
for resp in authorize_res:
@@ -302,9 +274,8 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.47')
rule_name = policies.POLICY_ROOT % 'index'
authorize_res, unauthorize_res = self.common_policy_check(
self.all_authorized_contexts,
self.all_unauthorized_contexts,
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_project_authorized_contexts,
rule_name, self.server_ctrl._action_rebuild,
req, self.instance.uuid,
body={'rebuild': {"imageRef": uuids.fake_id}},
@@ -323,9 +294,8 @@ class FlavorExtraSpecsPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.47')
rule_name = policies.POLICY_ROOT % 'index'
authorize_res, unauthorize_res = self.common_policy_check(
self.all_authorized_contexts,
self.all_unauthorized_contexts,
authorize_res, unauthorize_res = self.common_policy_auth(
self.all_project_authorized_contexts,
rule_name, self.server_ctrl.update,
req, self.instance.uuid,
body={'server': {'name': 'test'}},
@@ -350,32 +320,44 @@ class FlavorExtraSpecsScopeTypePolicyTest(FlavorExtraSpecsPolicyTest):
super(FlavorExtraSpecsScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# Check that all system scoped are able to get flavor extra specs.
self.all_system_authorized_contexts = [
self.system_admin_context, self.system_member_context,
self.system_reader_context, self.system_foo_context
]
self.all_system_unauthorized_contexts = [
self.legacy_admin_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context
]
# Check that system admin is able to create, update and delete flavor
# extra specs.
self.admin_authorized_contexts = [
self.system_admin_context]
# Check that non-system admin is not able to create, update and
# delete flavor extra specs.
self.admin_unauthorized_contexts = [
self.legacy_admin_context, self.project_admin_context,
self.system_member_context, self.system_reader_context,
self.system_foo_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context
]
# Only system users are authorized for system APIs
self.all_system_authorized_contexts = self.all_system_contexts
# Only system_admin can do system admin things
self.admin_authorized_contexts = [self.system_admin_context]
# Scope checking is in effect, so break apart project/system
# authorization. Note that even for the server tests above, we
# are technically authorizing against a server-embedded flavor
# (which has no project affiliation like the actual flavor it
# came from) and thus the other_project_* contexts are
# technically valid here. In reality, failure for
# other_project_* to get the server itself would prevent those
# projects from seeing the flavor extra_specs for it.
self.all_project_authorized_contexts = self.all_project_contexts
self.all_system_authorized_contexts = self.all_system_contexts
class FlavorExtraSpecsNoLegacyNoScopeTest(FlavorExtraSpecsPolicyTest):
"""Test Flavor Extra Specs API policies with deprecated rules
disabled, but scope checking still disabled.
"""
without_deprecated_rules = True
def setUp(self):
super(FlavorExtraSpecsNoLegacyNoScopeTest, self).setUp()
# Disabling legacy rules means that random roles no longer
# have power, but without scope checking there is no
# difference between project and system
everything_but_foo = (
self.all_project_contexts | self.all_system_contexts) - set([
self.system_foo_context,
self.project_foo_context,
])
self.reduce_set('all_project_authorized', everything_but_foo)
self.reduce_set('all_system_authorized', everything_but_foo)
self.reduce_set('all_authorized', everything_but_foo)
class FlavorExtraSpecsNoLegacyPolicyTest(FlavorExtraSpecsScopeTypePolicyTest):
@@ -387,28 +369,19 @@ class FlavorExtraSpecsNoLegacyPolicyTest(FlavorExtraSpecsScopeTypePolicyTest):
def setUp(self):
super(FlavorExtraSpecsNoLegacyPolicyTest, self).setUp()
# Check that system or project reader are able to get flavor
# extra specs.
self.all_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.system_member_context,
self.system_reader_context, self.other_project_member_context,
self.other_project_reader_context
]
self.all_unauthorized_contexts = [
self.project_foo_context, self.system_foo_context
]
# Check that all system scoped reader are able to get flavor
# extra specs.
self.all_system_authorized_contexts = [
self.system_admin_context, self.system_member_context,
self.system_reader_context
]
self.all_system_unauthorized_contexts = [
self.legacy_admin_context, self.system_foo_context,
self.project_admin_context, self.project_member_context,
self.project_reader_context, self.project_foo_context,
self.other_project_member_context,
self.other_project_reader_context
]
# Non-legacy rules do not imply random roles have any
# access. Same note as above, regarding other_project_*
# contexts. With scope checking enabled, project and system
# contexts stay separate.
self.reduce_set(
'all_project_authorized',
self.all_project_contexts - set([self.project_foo_context]))
self.reduce_set(
'all_system_authorized',
self.all_system_contexts - set([self.system_foo_context]))
everything_but_foo = (
self.all_project_contexts | self.all_system_contexts) - set([
self.system_foo_context,
self.project_foo_context,
])
self.reduce_set('all_authorized', everything_but_foo)
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -306,7 +306,7 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
self.non_admin_context = context.RequestContext('fake', 'fake',
roles=['member'])
self.admin_context = context.RequestContext('fake', 'fake', True,
roles=['member'])
roles=['admin', 'member'])
self.target = {}
self.fake_policy = jsonutils.loads(fake_policy.policy_data)