summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nova/policies/base.py5
-rw-r--r--nova/policies/server_groups.py21
-rw-r--r--nova/tests/unit/policies/base.py2
-rw-r--r--nova/tests/unit/policies/test_server_groups.py114
4 files changed, 123 insertions, 19 deletions
diff --git a/nova/policies/base.py b/nova/policies/base.py
index 96b9d8e91a..c54848e3b5 100644
--- a/nova/policies/base.py
+++ b/nova/policies/base.py
@@ -115,7 +115,10 @@ rules = [
policy.RuleDefault(
"project_member_api",
"role:member and project_id:%(project_id)s",
- "Default rule for Project level non admin APIs."),
+ "Default rule for Project level non admin APIs.",
+ deprecated_rule=DEPRECATED_ADMIN_OR_OWNER_POLICY,
+ deprecated_reason=DEPRECATED_REASON,
+ deprecated_since='21.0.0'),
policy.RuleDefault(
"project_reader_api",
"role:reader and project_id:%(project_id)s",
diff --git a/nova/policies/server_groups.py b/nova/policies/server_groups.py
index e9b95d316d..55176b8a6a 100644
--- a/nova/policies/server_groups.py
+++ b/nova/policies/server_groups.py
@@ -24,7 +24,7 @@ POLICY_ROOT = 'os_compute_api:os-server-groups:%s'
server_groups_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'create',
- check_str=base.RULE_ADMIN_OR_OWNER,
+ check_str=base.PROJECT_MEMBER,
description="Create a new server group",
operations=[
{
@@ -32,11 +32,20 @@ server_groups_policies = [
'method': 'POST'
}
],
- scope_types=['system', 'project']
+ # (NOTE)gmann: Reason for 'project' only scope:
+ # POST SG need project_id to create the serve groups
+ # system scope members do not have project id for which
+ # SG needs to be created.
+ # If we allow system scope role also then created SG will have
+ # project_id of system role, not the one he/she wants to create the SG
+ # for (nobody can create the SG for other projects because API does
+ # not take project id in request ). So keeping this scoped to project
+ # only as these roles are the only ones who will be creating SG.
+ scope_types=['project']
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
- check_str=base.RULE_ADMIN_OR_OWNER,
+ check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
description="Delete a server group",
operations=[
{
@@ -48,7 +57,7 @@ server_groups_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
- check_str=base.RULE_ADMIN_OR_OWNER,
+ check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="List all server groups",
operations=[
{
@@ -60,7 +69,7 @@ server_groups_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index:all_projects',
- check_str=base.RULE_ADMIN_API,
+ check_str=base.SYSTEM_READER,
description="List all server groups for all projects",
operations=[
{
@@ -72,7 +81,7 @@ server_groups_policies = [
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
- check_str=base.RULE_ADMIN_OR_OWNER,
+ check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="Show details of a server group",
operations=[
{
diff --git a/nova/tests/unit/policies/base.py b/nova/tests/unit/policies/base.py
index b0076e17c5..6825edffaa 100644
--- a/nova/tests/unit/policies/base.py
+++ b/nova/tests/unit/policies/base.py
@@ -114,6 +114,8 @@ class BasePolicyTest(test.TestCase):
"role:admin and system_scope:all",
"system_reader_api":
"role:reader and system_scope:all",
+ "project_member_api":
+ "role:member and project_id:%(project_id)s",
})
self.policy.set_rules(self.rules_without_deprecation,
overwrite=False)
diff --git a/nova/tests/unit/policies/test_server_groups.py b/nova/tests/unit/policies/test_server_groups.py
index babdab3f75..73d8c0f12e 100644
--- a/nova/tests/unit/policies/test_server_groups.py
+++ b/nova/tests/unit/policies/test_server_groups.py
@@ -45,22 +45,35 @@ class ServerGroupPolicyTest(base.BasePolicyTest):
user_id='u2', policies=[], members=[])]
self.mock_get.return_value = self.sg[0]
- # Check that admin or and owner is able to get and delete
+ # Check that admin or and owner is able to delete
# the server group.
self.admin_or_owner_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]
- # Check that non-admin/owner is not able to get and delete
+ # Check that non-admin/owner is not able to delete
# the server group.
self.admin_or_owner_unauthorized_contexts = [
self.system_member_context, self.system_reader_context,
self.system_foo_context,
self.other_project_member_context
]
-
- # Check that everyone is able to list and create
- # theie own server group.
+ # Check that system reader or owner is able to get
+ # the server group. Due to old default everyone
+ # is allowed to perform this operation.
+ self.system_reader_or_owner_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.project_foo_context
+ ]
+ self.system_reader_or_owner_unauthorized_contexts = [
+ self.system_foo_context,
+ self.other_project_member_context
+ ]
+ # Check that everyone is able to list
+ # theie own server group. Due to old defaults everyone
+ # is able to list their server groups.
self.everyone_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context, self.project_member_context,
@@ -70,6 +83,16 @@ class ServerGroupPolicyTest(base.BasePolicyTest):
self.other_project_member_context]
self.everyone_unauthorized_contexts = [
]
+ # Check that project member is able to create server group.
+ # Due to old defaults everyone is able to list their server groups.
+ self.project_member_authorized_contexts = [
+ self.legacy_admin_context, self.system_admin_context,
+ self.project_admin_context, self.project_member_context,
+ self.system_member_context, self.project_reader_context,
+ self.project_foo_context, self.system_reader_context,
+ self.system_foo_context,
+ self.other_project_member_context]
+ self.project_member_unauthorized_contexts = []
@mock.patch('nova.objects.InstanceGroupList.get_by_project_id')
def test_index_server_groups_policy(self, mock_get):
@@ -105,19 +128,20 @@ class ServerGroupPolicyTest(base.BasePolicyTest):
def test_show_server_groups_policy(self):
rule_name = policies.POLICY_ROOT % 'show'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller.show,
- self.req, uuids.fake_id)
+ self.common_policy_check(
+ self.system_reader_or_owner_authorized_contexts,
+ self.system_reader_or_owner_unauthorized_contexts,
+ rule_name,
+ self.controller.show,
+ self.req, uuids.fake_id)
@mock.patch('nova.objects.Quotas.check_deltas')
def test_create_server_groups_policy(self, mock_quota):
rule_name = policies.POLICY_ROOT % 'create'
body = {'server_group': {'name': 'fake',
'policies': ['affinity']}}
- self.common_policy_check(self.everyone_authorized_contexts,
- self.everyone_unauthorized_contexts,
+ self.common_policy_check(self.project_member_authorized_contexts,
+ self.project_member_unauthorized_contexts,
rule_name,
self.controller.create,
self.req, body=body)
@@ -146,6 +170,19 @@ class ServerGroupScopeTypePolicyTest(ServerGroupPolicyTest):
super(ServerGroupScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
+ # Check if project scoped can create the server group.
+ self.project_member_authorized_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
+ ]
+ # Check if non-project scoped cannot create the server group.
+ self.project_member_unauthorized_contexts = [
+ self.system_admin_context, self.system_member_context,
+ self.system_reader_context, self.system_foo_context
+ ]
+
# TODO(gmann): Test this with system scope once we remove
# the hardcoded admin check
def test_index_all_project_server_groups_policy(self):
@@ -158,3 +195,56 @@ class ServerGroupNoLegacyPolicyTest(ServerGroupScopeTypePolicyTest):
access system APIs.
"""
without_deprecated_rules = True
+
+ def setUp(self):
+ super(ServerGroupNoLegacyPolicyTest, self).setUp()
+
+ # Check that system admin or and owner is able to delete
+ # the server group.
+ self.admin_or_owner_authorized_contexts = [
+ self.system_admin_context,
+ self.project_admin_context, self.project_member_context,
+ ]
+ # Check that non-system admin/owner is not able to delete
+ # the server group.
+ self.admin_or_owner_unauthorized_contexts = [
+ self.legacy_admin_context, self.system_member_context,
+ self.system_reader_context, self.system_foo_context,
+ self.project_reader_context, self.project_foo_context,
+ self.other_project_member_context
+ ]
+ # Check that system reader or owner is able to get
+ # the server group.
+ self.system_reader_or_owner_authorized_contexts = [
+ 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.system_reader_or_owner_unauthorized_contexts = [
+ self.legacy_admin_context, self.system_foo_context,
+ self.other_project_member_context, self.project_foo_context
+ ]
+ self.everyone_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.everyone_unauthorized_contexts = [
+ self.project_foo_context,
+ self.system_foo_context
+ ]
+ # Check if project member can create the server group.
+ self.project_member_authorized_contexts = [
+ self.legacy_admin_context, self.project_admin_context,
+ self.project_member_context, self.other_project_member_context
+ ]
+ # Check if non-project member cannot create the server group.
+ self.project_member_unauthorized_contexts = [
+ self.system_admin_context,
+ self.system_member_context, self.system_reader_context,
+ self.system_foo_context, self.project_reader_context,
+ self.project_foo_context,
+ ]