Add new default roles in security_groups policies
This adds new defaults roles in security_groups API policies. These policies are made granular and default to PROJECT_READER_OR_SYSTEM_READER and PROJECT_MEMBER_OR_SYSTEM_ADMIN. Partial implement blueprint policy-defaults-refresh-deprecated-apis Change-Id: Ie1ea066e9683fc44d486bcde1eb0f01fca7645c7
This commit is contained in:
parent
2939847226
commit
a20ab7016e
|
@ -37,12 +37,6 @@ LOG = logging.getLogger(__name__)
|
|||
SG_NOT_FOUND = object()
|
||||
|
||||
|
||||
def _authorize_context(req):
|
||||
context = req.environ['nova.context']
|
||||
context.can(sg_policies.BASE_POLICY_NAME)
|
||||
return context
|
||||
|
||||
|
||||
class SecurityGroupControllerBase(object):
|
||||
"""Base class for Security Group controllers."""
|
||||
|
||||
|
@ -155,7 +149,8 @@ class SecurityGroupController(SecurityGroupControllerBase, wsgi.Controller):
|
|||
@wsgi.expected_errors((400, 404))
|
||||
def show(self, req, id):
|
||||
"""Return data about the given security group."""
|
||||
context = _authorize_context(req)
|
||||
context = req.environ['nova.context']
|
||||
context.can(sg_policies.POLICY_NAME % 'show')
|
||||
|
||||
try:
|
||||
id = security_group_api.validate_id(id)
|
||||
|
@ -173,7 +168,8 @@ class SecurityGroupController(SecurityGroupControllerBase, wsgi.Controller):
|
|||
@wsgi.response(202)
|
||||
def delete(self, req, id):
|
||||
"""Delete a security group."""
|
||||
context = _authorize_context(req)
|
||||
context = req.environ['nova.context']
|
||||
context.can(sg_policies.POLICY_NAME % 'delete')
|
||||
|
||||
try:
|
||||
id = security_group_api.validate_id(id)
|
||||
|
@ -189,7 +185,8 @@ class SecurityGroupController(SecurityGroupControllerBase, wsgi.Controller):
|
|||
@wsgi.expected_errors(404)
|
||||
def index(self, req):
|
||||
"""Returns a list of security groups."""
|
||||
context = _authorize_context(req)
|
||||
context = req.environ['nova.context']
|
||||
context.can(sg_policies.POLICY_NAME % 'get')
|
||||
|
||||
search_opts = {}
|
||||
search_opts.update(req.GET)
|
||||
|
@ -210,7 +207,8 @@ class SecurityGroupController(SecurityGroupControllerBase, wsgi.Controller):
|
|||
@wsgi.expected_errors((400, 403))
|
||||
def create(self, req, body):
|
||||
"""Creates a new security group."""
|
||||
context = _authorize_context(req)
|
||||
context = req.environ['nova.context']
|
||||
context.can(sg_policies.POLICY_NAME % 'create')
|
||||
|
||||
security_group = self._from_body(body, 'security_group')
|
||||
|
||||
|
@ -235,7 +233,8 @@ class SecurityGroupController(SecurityGroupControllerBase, wsgi.Controller):
|
|||
@wsgi.expected_errors((400, 404))
|
||||
def update(self, req, id, body):
|
||||
"""Update a security group."""
|
||||
context = _authorize_context(req)
|
||||
context = req.environ['nova.context']
|
||||
context.can(sg_policies.POLICY_NAME % 'update')
|
||||
|
||||
try:
|
||||
id = security_group_api.validate_id(id)
|
||||
|
@ -270,8 +269,8 @@ class SecurityGroupRulesController(SecurityGroupControllerBase,
|
|||
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
|
||||
@wsgi.expected_errors((400, 403, 404))
|
||||
def create(self, req, body):
|
||||
context = _authorize_context(req)
|
||||
|
||||
context = req.environ['nova.context']
|
||||
context.can(sg_policies.POLICY_NAME % 'rule:create')
|
||||
sg_rule = self._from_body(body, 'security_group_rule')
|
||||
group_id = sg_rule.get('group_id')
|
||||
source_group = {}
|
||||
|
@ -345,7 +344,8 @@ class SecurityGroupRulesController(SecurityGroupControllerBase,
|
|||
@wsgi.expected_errors((400, 404, 409))
|
||||
@wsgi.response(202)
|
||||
def delete(self, req, id):
|
||||
context = _authorize_context(req)
|
||||
context = req.environ['nova.context']
|
||||
context.can(sg_policies.POLICY_NAME % 'rule:delete')
|
||||
|
||||
try:
|
||||
id = security_group_api.validate_id(id)
|
||||
|
|
|
@ -35,37 +35,103 @@ in nova 23.0.0 release.
|
|||
|
||||
security_groups_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
name=BASE_POLICY_NAME,
|
||||
check_str=base.RULE_ADMIN_OR_OWNER,
|
||||
description="""List, show, add, or remove security groups.
|
||||
|
||||
APIs which are directly related to security groups resource are deprecated:
|
||||
Lists, shows information for, creates, updates and deletes
|
||||
security groups. Creates and deletes security group rules. All these
|
||||
APIs are deprecated.""",
|
||||
name=POLICY_NAME % 'get',
|
||||
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
|
||||
description="List security groups. This API is deprecated.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/os-security-groups'
|
||||
},
|
||||
}
|
||||
],
|
||||
scope_types=['system', 'project'],
|
||||
deprecated_rule=DEPRECATED_POLICY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since='22.0.0'),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=POLICY_NAME % 'show',
|
||||
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
|
||||
description="Show security group. This API is deprecated.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/os-security-groups/{security_group_id}'
|
||||
},
|
||||
}
|
||||
],
|
||||
scope_types=['system', 'project'],
|
||||
deprecated_rule=DEPRECATED_POLICY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since='22.0.0'),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=POLICY_NAME % 'create',
|
||||
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
description="Create security group. This API is deprecated.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/os-security-groups'
|
||||
},
|
||||
}
|
||||
],
|
||||
scope_types=['system', 'project'],
|
||||
deprecated_rule=DEPRECATED_POLICY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since='22.0.0'),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=POLICY_NAME % 'update',
|
||||
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
description="Update security group. This API is deprecated.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'PUT',
|
||||
'path': '/os-security-groups/{security_group_id}'
|
||||
},
|
||||
}
|
||||
],
|
||||
scope_types=['system', 'project'],
|
||||
deprecated_rule=DEPRECATED_POLICY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since='22.0.0'),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=POLICY_NAME % 'delete',
|
||||
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
description="Delete security group. This API is deprecated.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/os-security-groups/{security_group_id}'
|
||||
},
|
||||
],
|
||||
scope_types=['system', 'project']),
|
||||
scope_types=['system', 'project'],
|
||||
deprecated_rule=DEPRECATED_POLICY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since='22.0.0'),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=POLICY_NAME % 'rule:create',
|
||||
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
description="Create security group Rule. This API is deprecated.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/os-security-group-rules'
|
||||
}
|
||||
],
|
||||
scope_types=['system', 'project'],
|
||||
deprecated_rule=DEPRECATED_POLICY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since='22.0.0'),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=POLICY_NAME % 'rule:delete',
|
||||
check_str=base.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
description="Delete security group Rule. This API is deprecated.",
|
||||
operations=[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/os-security-group-rules/{security_group_id}'
|
||||
},
|
||||
],
|
||||
scope_types=['system', 'project'],
|
||||
deprecated_rule=DEPRECATED_POLICY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since='22.0.0'),
|
||||
policy.DocumentedRuleDefault(
|
||||
name=POLICY_NAME % 'list',
|
||||
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
|
||||
|
|
|
@ -135,6 +135,13 @@ policy_data = """
|
|||
"os_compute_api:os-security-groups:list": "",
|
||||
"os_compute_api:os-security-groups:add": "",
|
||||
"os_compute_api:os-security-groups:remove": "",
|
||||
"os_compute_api:os-security-groups:get": "",
|
||||
"os_compute_api:os-security-groups:show": "",
|
||||
"os_compute_api:os-security-groups:create": "",
|
||||
"os_compute_api:os-security-groups:delete": "",
|
||||
"os_compute_api:os-security-groups:update": "",
|
||||
"os_compute_api:os-security-groups:rule:create": "",
|
||||
"os_compute_api:os-security-groups:rule:delete": "",
|
||||
"os_compute_api:os-server-diagnostics": "",
|
||||
"os_compute_api:os-server-password:show": "",
|
||||
"os_compute_api:os-server-password:clear": "",
|
||||
|
|
|
@ -127,7 +127,7 @@ class SecurityGroupsPolicyTest(base.BasePolicyTest):
|
|||
# as target to policy and always pass. If requester is not admin
|
||||
# or owner of security groups then neutron will be returning the
|
||||
# appropriate error.
|
||||
self.everyone_authorized_contexts = [
|
||||
self.reader_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,
|
||||
|
@ -136,22 +136,26 @@ class SecurityGroupsPolicyTest(base.BasePolicyTest):
|
|||
self.system_foo_context,
|
||||
self.other_project_member_context
|
||||
]
|
||||
self.everyone_unauthorized_contexts = []
|
||||
self.reader_unauthorized_contexts = []
|
||||
self.sys_admin_or_owner_authorized_contexts = (
|
||||
self.reader_authorized_contexts)
|
||||
self.sys_admin_or_owner_unauthorized_contexts = (
|
||||
self.reader_unauthorized_contexts)
|
||||
|
||||
@mock.patch('nova.network.security_group_api.list')
|
||||
def test_list_security_groups_policy(self, mock_get):
|
||||
rule_name = policies.BASE_POLICY_NAME
|
||||
self.common_policy_check(self.everyone_authorized_contexts,
|
||||
self.everyone_unauthorized_contexts,
|
||||
rule_name = policies.POLICY_NAME % 'get'
|
||||
self.common_policy_check(self.reader_authorized_contexts,
|
||||
self.reader_unauthorized_contexts,
|
||||
rule_name,
|
||||
self.controller.index,
|
||||
self.req)
|
||||
|
||||
@mock.patch('nova.network.security_group_api.get')
|
||||
def test_show_security_groups_policy(self, mock_get):
|
||||
rule_name = policies.BASE_POLICY_NAME
|
||||
self.common_policy_check(self.everyone_authorized_contexts,
|
||||
self.everyone_unauthorized_contexts,
|
||||
rule_name = policies.POLICY_NAME % 'show'
|
||||
self.common_policy_check(self.reader_authorized_contexts,
|
||||
self.reader_unauthorized_contexts,
|
||||
rule_name,
|
||||
self.controller.show,
|
||||
self.req, uuids.fake_id)
|
||||
|
@ -159,24 +163,24 @@ class SecurityGroupsPolicyTest(base.BasePolicyTest):
|
|||
@mock.patch('nova.network.security_group_api.get')
|
||||
@mock.patch('nova.network.security_group_api.update_security_group')
|
||||
def test_update_security_groups_policy(self, mock_update, mock_get):
|
||||
rule_name = policies.BASE_POLICY_NAME
|
||||
rule_name = policies.POLICY_NAME % 'update'
|
||||
body = {'security_group': {
|
||||
'name': 'test',
|
||||
'description': 'test-desc'}}
|
||||
self.common_policy_check(self.everyone_authorized_contexts,
|
||||
self.everyone_unauthorized_contexts,
|
||||
self.common_policy_check(self.sys_admin_or_owner_authorized_contexts,
|
||||
self.sys_admin_or_owner_unauthorized_contexts,
|
||||
rule_name,
|
||||
self.controller.update,
|
||||
self.req, uuids.fake_id, body=body)
|
||||
|
||||
@mock.patch('nova.network.security_group_api.create_security_group')
|
||||
def test_create_security_groups_policy(self, mock_create):
|
||||
rule_name = policies.BASE_POLICY_NAME
|
||||
rule_name = policies.POLICY_NAME % 'create'
|
||||
body = {'security_group': {
|
||||
'name': 'test',
|
||||
'description': 'test-desc'}}
|
||||
self.common_policy_check(self.everyone_authorized_contexts,
|
||||
self.everyone_unauthorized_contexts,
|
||||
self.common_policy_check(self.sys_admin_or_owner_authorized_contexts,
|
||||
self.sys_admin_or_owner_unauthorized_contexts,
|
||||
rule_name,
|
||||
self.controller.create,
|
||||
self.req, body=body)
|
||||
|
@ -184,9 +188,9 @@ class SecurityGroupsPolicyTest(base.BasePolicyTest):
|
|||
@mock.patch('nova.network.security_group_api.get')
|
||||
@mock.patch('nova.network.security_group_api.destroy')
|
||||
def test_delete_security_groups_policy(self, mock_destroy, mock_get):
|
||||
rule_name = policies.BASE_POLICY_NAME
|
||||
self.common_policy_check(self.everyone_authorized_contexts,
|
||||
self.everyone_unauthorized_contexts,
|
||||
rule_name = policies.POLICY_NAME % 'delete'
|
||||
self.common_policy_check(self.sys_admin_or_owner_authorized_contexts,
|
||||
self.sys_admin_or_owner_unauthorized_contexts,
|
||||
rule_name,
|
||||
self.controller.delete,
|
||||
self.req, uuids.fake_id)
|
||||
|
@ -194,13 +198,13 @@ class SecurityGroupsPolicyTest(base.BasePolicyTest):
|
|||
@mock.patch('nova.network.security_group_api.get')
|
||||
@mock.patch('nova.network.security_group_api.create_security_group_rule')
|
||||
def test_create_security_group_rules_policy(self, mock_create, mock_get):
|
||||
rule_name = policies.BASE_POLICY_NAME
|
||||
rule_name = policies.POLICY_NAME % 'rule:create'
|
||||
body = {'security_group_rule': {
|
||||
'ip_protocol': 'test', 'group_id': uuids.fake_id,
|
||||
'parent_group_id': uuids.fake_id,
|
||||
'from_port': 22, 'from_port': 22}}
|
||||
self.common_policy_check(self.everyone_authorized_contexts,
|
||||
self.everyone_unauthorized_contexts,
|
||||
self.common_policy_check(self.sys_admin_or_owner_authorized_contexts,
|
||||
self.sys_admin_or_owner_unauthorized_contexts,
|
||||
rule_name,
|
||||
self.rule_ctr.create,
|
||||
self.req, body=body)
|
||||
|
@ -210,9 +214,9 @@ class SecurityGroupsPolicyTest(base.BasePolicyTest):
|
|||
@mock.patch('nova.network.security_group_api.remove_rules')
|
||||
def test_delete_security_group_rules_policy(self, mock_remove, mock_get,
|
||||
mock_rules):
|
||||
rule_name = policies.BASE_POLICY_NAME
|
||||
self.common_policy_check(self.everyone_authorized_contexts,
|
||||
self.everyone_unauthorized_contexts,
|
||||
rule_name = policies.POLICY_NAME % 'rule:delete'
|
||||
self.common_policy_check(self.sys_admin_or_owner_authorized_contexts,
|
||||
self.sys_admin_or_owner_unauthorized_contexts,
|
||||
rule_name,
|
||||
self.rule_ctr.delete,
|
||||
self.req, uuids.fake_id)
|
||||
|
@ -297,3 +301,51 @@ class ServerSecurityGroupsNoLegacyPolicyTest(
|
|||
self.system_foo_context, self.other_project_member_context,
|
||||
self.other_project_reader_context
|
||||
]
|
||||
|
||||
|
||||
class SecurityGroupsNoLegacyPolicyTest(SecurityGroupsScopeTypePolicyTest):
|
||||
"""Test Security Groups APIs policies with system scope enabled,
|
||||
and no more deprecated rules that allow the legacy admin API to
|
||||
access system_admin_or_owner APIs.
|
||||
"""
|
||||
without_deprecated_rules = True
|
||||
rules_without_deprecation = {
|
||||
policies.POLICY_NAME % 'get':
|
||||
base_policy.PROJECT_READER_OR_SYSTEM_READER,
|
||||
policies.POLICY_NAME % 'show':
|
||||
base_policy.PROJECT_READER_OR_SYSTEM_READER,
|
||||
policies.POLICY_NAME % 'create':
|
||||
base_policy.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
policies.POLICY_NAME % 'update':
|
||||
base_policy.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
policies.POLICY_NAME % 'delete':
|
||||
base_policy.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
policies.POLICY_NAME % 'rule:create':
|
||||
base_policy.PROJECT_MEMBER_OR_SYSTEM_ADMIN,
|
||||
policies.POLICY_NAME % 'rule:delete':
|
||||
base_policy.PROJECT_MEMBER_OR_SYSTEM_ADMIN}
|
||||
|
||||
def setUp(self):
|
||||
super(SecurityGroupsNoLegacyPolicyTest, self).setUp()
|
||||
|
||||
self.reader_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.reader_unauthorized_contexts = [
|
||||
self.project_foo_context,
|
||||
self.system_foo_context
|
||||
]
|
||||
self.sys_admin_or_owner_authorized_contexts = [
|
||||
self.system_admin_context, self.system_member_context,
|
||||
self.project_admin_context, self.project_member_context,
|
||||
self.legacy_admin_context, self.other_project_member_context
|
||||
]
|
||||
self.sys_admin_or_owner_unauthorized_contexts = [
|
||||
self.system_reader_context,
|
||||
self.project_reader_context, self.project_foo_context,
|
||||
self.system_foo_context, self.other_project_reader_context
|
||||
]
|
||||
|
|
|
@ -431,7 +431,11 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
|
|||
"os_compute_api:os-networks:view",
|
||||
"os_compute_api:os-rescue",
|
||||
"os_compute_api:os-unrescue",
|
||||
"os_compute_api:os-security-groups",
|
||||
"os_compute_api:os-security-groups:create",
|
||||
"os_compute_api:os-security-groups:update",
|
||||
"os_compute_api:os-security-groups:delete",
|
||||
"os_compute_api:os-security-groups:rule:create",
|
||||
"os_compute_api:os-security-groups:rule:delete",
|
||||
"os_compute_api:os-security-groups:add",
|
||||
"os_compute_api:os-security-groups:remove",
|
||||
"os_compute_api:os-server-password:clear",
|
||||
|
@ -479,6 +483,8 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
|
|||
|
||||
self.system_reader_or_owner_rules = (
|
||||
"os_compute_api:os-simple-tenant-usage:show",
|
||||
"os_compute_api:os-security-groups:get",
|
||||
"os_compute_api:os-security-groups:show",
|
||||
"os_compute_api:os-security-groups:list",
|
||||
"os_compute_api:os-volumes-attachments:index",
|
||||
"os_compute_api:os-volumes-attachments:show",
|
||||
|
|
Loading…
Reference in New Issue