summaryrefslogtreecommitdiff
path: root/nova/tests/unit/policies/test_servers.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/tests/unit/policies/test_servers.py')
-rw-r--r--nova/tests/unit/policies/test_servers.py864
1 files changed, 422 insertions, 442 deletions
diff --git a/nova/tests/unit/policies/test_servers.py b/nova/tests/unit/policies/test_servers.py
index 33aadb948f..eee1e4ba51 100644
--- a/nova/tests/unit/policies/test_servers.py
+++ b/nova/tests/unit/policies/test_servers.py
@@ -10,9 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+import functools
+from unittest import mock
import fixtures
-import mock
from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils import timeutils
@@ -20,12 +21,14 @@ from nova.api.openstack.compute import migrate_server
from nova.api.openstack.compute import servers
from nova.compute import api as compute
from nova.compute import vm_states
+import nova.conf
from nova import exception
from nova.network import model
from nova.network import neutron
from nova import objects
from nova.objects import fields
from nova.objects.instance_group import InstanceGroup
+from nova.policies import base as base_policy
from nova.policies import extended_server_attributes as ea_policies
from nova.policies import servers as policies
from nova.tests.unit.api.openstack import fakes
@@ -33,6 +36,8 @@ from nova.tests.unit import fake_flavor
from nova.tests.unit import fake_instance
from nova.tests.unit.policies import base
+CONF = nova.conf.CONF
+
class ServersPolicyTest(base.BasePolicyTest):
"""Test Servers APIs policies with all possible context.
@@ -114,137 +119,41 @@ class ServersPolicyTest(base.BasePolicyTest):
'OS-EXT-SRV-ATTR:user_data'
]
- # Check that admin or and owner is able to update, delete
- # or perform server action.
- self.admin_or_owner_authorized_contexts = [
+ # Users that can take action on *our* project resources
+ self.project_action_authorized_contexts = set([
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 update, delete
- # or perform server action.
- self.admin_or_owner_unauthorized_contexts = [
- self.system_member_context, self.system_reader_context,
- self.system_foo_context,
- self.other_project_member_context,
- self.other_project_reader_context
- ]
+ self.project_reader_context, self.project_foo_context,
+ ])
- # Check that system reader or owner is able to get
- # the server.
- 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,
- self.other_project_reader_context
- ]
+ # Users that can read *our* project resources
+ self.project_reader_authorized_contexts = (
+ self.project_action_authorized_contexts)
- # Check that everyone is able to list their own server.
- 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.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.everyone_unauthorized_contexts = [
- ]
- # Check that admin is able to create server with host request
- # and get server extended attributes or host status.
- 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 server with host request
- # and get server extended attributes or host status.
- 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
- ]
- # Check that sustem reader is able to list the server
- # for all projects.
- self.system_reader_authorized_contexts = [
- self.legacy_admin_context, self.system_admin_context,
- self.project_admin_context, self.system_member_context,
- self.system_reader_context]
- # Check that non-system reader is not able to list the server
- # for all projects.
- self.system_reader_unauthorized_contexts = [
- 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
- ]
- # Check that project member is able to create serve
- self.project_member_authorized_contexts = [
+ # Users that _see_ project-scoped resources that they own
+ self.everyone_authorized_contexts = set(self.all_contexts)
+
+ # Users that can _do_ things to project-scoped resources they own
+ self.project_member_authorized_contexts = set(self.all_contexts)
+
+ # Users able to do admin things on project resources
+ self.project_admin_authorized_contexts = set([
self.legacy_admin_context, self.system_admin_context,
- self.project_admin_context, self.project_member_context,
- self.system_member_context, self.system_reader_context,
- self.other_project_member_context, self.system_foo_context,
- self.project_reader_context, self.project_foo_context,
- self.other_project_reader_context]
- # Check that non-project member is not able to create server
- self.project_member_unauthorized_contexts = [
- ]
- # Check that project admin is able to create server with requested
- # destination.
- self.project_admin_authorized_contexts = [
+ self.project_admin_context])
+
+ # Admin (for APIs does not pass the project id as policy target
+ # for example, create server, list detail server) able to get
+ # all projects servers, create server on specific host etc.
+ # This is admin on any project because policy does not check
+ # the project id but they will be able to create server, get
+ # servers(unless all-tenant policy is allowed) of their own
+ # project only.
+ self.all_projects_admin_authorized_contexts = set([
self.legacy_admin_context, self.system_admin_context,
- self.project_admin_context]
- # Check that non-project admin is not able to create server with
- # requested destination
- self.project_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
- ]
- # Check that no one is able to resize cross cell.
+ self.project_admin_context])
+
+ # Users able to do cross-cell migrations
self.cross_cell_authorized_contexts = []
- self.cross_cell_unauthorized_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]
- # Check that admin is able to access the zero disk flavor
- # and external network policies.
- self.zero_disk_external_net_authorized_contexts = [
- self.legacy_admin_context, self.system_admin_context,
- self.project_admin_context]
- # Check that non-admin is not able to caccess the zero disk flavor
- # and external network policies.
- self.zero_disk_external_net_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
- ]
- # Check that admin is able to get server extended attributes
- # or host status.
- self.server_attr_admin_authorized_contexts = [
- self.legacy_admin_context, self.system_admin_context,
- self.project_admin_context]
- # Check that non-admin is not able to get server extended attributes
- # or host status.
- self.server_attr_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
- ]
def test_index_server_policy(self):
@@ -261,9 +170,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.mock_get_all.side_effect = fake_get_all
rule_name = policies.SERVERS % 'index'
- self.common_policy_check(
+ self.common_policy_auth(
self.everyone_authorized_contexts,
- self.everyone_unauthorized_contexts,
rule_name,
self.controller.index,
self.req)
@@ -287,11 +195,16 @@ class ServersPolicyTest(base.BasePolicyTest):
self.mock_get_all.side_effect = fake_get_all
- self.common_policy_check(self.system_reader_authorized_contexts,
- self.system_reader_unauthorized_contexts,
- rule_name,
- self.controller.index,
- req)
+ if not CONF.oslo_policy.enforce_scope:
+ check_rule = rule_name
+ else:
+ check_rule = functools.partial(
+ base.rule_if_system, rule, rule_name)
+
+ self.common_policy_auth(self.all_projects_admin_authorized_contexts,
+ check_rule,
+ self.controller.index,
+ req)
@mock.patch('nova.compute.api.API.get_all')
def test_detail_list_server_policy(self, mock_get):
@@ -309,9 +222,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.mock_get_all.side_effect = fake_get_all
rule_name = policies.SERVERS % 'detail'
- self.common_policy_check(
+ self.common_policy_auth(
self.everyone_authorized_contexts,
- self.everyone_unauthorized_contexts,
rule_name,
self.controller.detail,
self.req)
@@ -335,11 +247,16 @@ class ServersPolicyTest(base.BasePolicyTest):
self.mock_get_all.side_effect = fake_get_all
- self.common_policy_check(self.system_reader_authorized_contexts,
- self.system_reader_unauthorized_contexts,
- rule_name,
- self.controller.detail,
- req)
+ if not CONF.oslo_policy.enforce_scope:
+ check_rule = rule_name
+ else:
+ check_rule = functools.partial(
+ base.rule_if_system, rule, rule_name)
+
+ self.common_policy_auth(self.all_projects_admin_authorized_contexts,
+ check_rule,
+ self.controller.detail,
+ req)
def test_index_server_allow_all_filters_policy(self):
# 'index' policy is checked before 'allow_all_filters' so
@@ -353,9 +270,9 @@ class ServersPolicyTest(base.BasePolicyTest):
expected_attrs=None, sort_keys=None, sort_dirs=None,
cell_down_support=False, all_tenants=False):
self.assertIsNotNone(search_opts)
- if context in self.system_reader_unauthorized_contexts:
+ if context not in self.all_projects_admin_authorized_contexts:
self.assertNotIn('host', search_opts)
- if context in self.system_reader_authorized_contexts:
+ if context in self.all_projects_admin_authorized_contexts:
self.assertIn('host', search_opts)
return objects.InstanceList(objects=self.servers)
@@ -363,9 +280,8 @@ class ServersPolicyTest(base.BasePolicyTest):
req = fakes.HTTPRequest.blank('/servers?host=1')
rule_name = policies.SERVERS % 'allow_all_filters'
- self.common_policy_check(
- self.system_reader_authorized_contexts,
- self.system_reader_unauthorized_contexts,
+ self.common_policy_auth(
+ self.all_projects_admin_authorized_contexts,
rule_name,
self.controller.index,
req, fatal=False)
@@ -382,18 +298,17 @@ class ServersPolicyTest(base.BasePolicyTest):
expected_attrs=None, sort_keys=None, sort_dirs=None,
cell_down_support=False, all_tenants=False):
self.assertIsNotNone(search_opts)
- if context in self.system_reader_unauthorized_contexts:
+ if context not in self.all_projects_admin_authorized_contexts:
self.assertNotIn('host', search_opts)
- if context in self.system_reader_authorized_contexts:
+ if context in self.all_projects_admin_authorized_contexts:
self.assertIn('host', search_opts)
return objects.InstanceList(objects=self.servers)
self.mock_get_all.side_effect = fake_get_all
req = fakes.HTTPRequest.blank('/servers?host=1')
rule_name = policies.SERVERS % 'allow_all_filters'
- self.common_policy_check(
- self.system_reader_authorized_contexts,
- self.system_reader_unauthorized_contexts,
+ self.common_policy_auth(
+ self.all_projects_admin_authorized_contexts,
rule_name,
self.controller.detail,
req, fatal=False)
@@ -401,22 +316,117 @@ class ServersPolicyTest(base.BasePolicyTest):
@mock.patch('nova.objects.BlockDeviceMappingList.bdms_by_instance_uuid')
def test_show_server_policy(self, mock_bdm):
rule_name = policies.SERVERS % 'show'
- self.common_policy_check(
- self.system_reader_or_owner_authorized_contexts,
- self.system_reader_or_owner_unauthorized_contexts,
+ # Show includes readers
+ self.common_policy_auth(
+ self.project_reader_authorized_contexts,
rule_name,
self.controller.show,
self.req, self.instance.uuid)
+ @mock.patch('nova.objects.BlockDeviceMappingList.bdms_by_instance_uuid')
+ @mock.patch('nova.compute.api.API.get_instance_host_status')
+ def test_server_show_with_extra_specs_policy(self, mock_get, mock_block):
+ rule = policies.SERVERS % 'show'
+ # server 'show' policy is checked before flavor extra specs
+ # policy so we have to allow it for everyone otherwise it will fail
+ # first for unauthorized contexts.
+ self.policy.set_rules({rule: "@"}, overwrite=False)
+ req = fakes.HTTPRequest.blank('', version='2.47')
+ rule_name = policies.SERVERS % 'show:flavor-extra-specs'
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_reader_authorized_contexts,
+ rule_name, self.controller.show, req,
+ self.instance.uuid, fatal=False)
+ for resp in authorize_res:
+ self.assertIn('extra_specs', resp['server']['flavor'])
+ for resp in unauthorize_res:
+ self.assertNotIn('extra_specs', resp['server']['flavor'])
+
+ @mock.patch('nova.compute.api.API.get_all')
+ def test_server_detail_with_extra_specs_policy(self, mock_get):
+
+ def fake_get_all(context, search_opts=None,
+ limit=None, marker=None,
+ expected_attrs=None, sort_keys=None, sort_dirs=None,
+ cell_down_support=False, all_tenants=False):
+ self.assertIsNotNone(search_opts)
+ if 'project_id' in search_opts or 'user_id' in search_opts:
+ return objects.InstanceList(objects=self.servers)
+ else:
+ raise
+
+ self.mock_get_all.side_effect = fake_get_all
+ rule = policies.SERVERS % 'detail'
+ # server 'detail' policy is checked before flavor extra specs
+ # policy so we have to allow it for everyone otherwise it will fail
+ # first for unauthorized contexts.
+ self.policy.set_rules({rule: "@"}, overwrite=False)
+ req = fakes.HTTPRequest.blank('', version='2.47')
+ rule_name = policies.SERVERS % 'show:flavor-extra-specs'
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.everyone_authorized_contexts,
+ rule_name, self.controller.detail, req,
+ fatal=False)
+ for resp in authorize_res:
+ self.assertIn('extra_specs', resp['servers'][0]['flavor'])
+ for resp in unauthorize_res:
+ self.assertNotIn('extra_specs', resp['servers'][0]['flavor'])
+
+ @mock.patch('nova.objects.BlockDeviceMappingList.bdms_by_instance_uuid')
+ @mock.patch('nova.compute.api.API.get_instance_host_status')
+ @mock.patch('nova.compute.api.API.rebuild')
+ def test_server_rebuild_with_extra_specs_policy(self, mock_rebuild,
+ mock_get, mock_bdm):
+ rule = policies.SERVERS % 'rebuild'
+ # server 'rebuild' policy is checked before flavor extra specs
+ # policy so we have to allow it for everyone otherwise it will fail
+ # first for unauthorized contexts.
+ self.policy.set_rules({rule: "@"}, overwrite=False)
+ req = fakes.HTTPRequest.blank('', version='2.47')
+ rule_name = policies.SERVERS % 'show:flavor-extra-specs'
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_reader_authorized_contexts,
+ rule_name, self.controller._action_rebuild,
+ req, self.instance.uuid,
+ body={'rebuild': {"imageRef": uuids.fake_id}},
+ fatal=False)
+ for resp in authorize_res:
+ self.assertIn('extra_specs', resp.obj['server']['flavor'])
+ for resp in unauthorize_res:
+ self.assertNotIn('extra_specs', resp.obj['server']['flavor'])
+
+ @mock.patch('nova.objects.BlockDeviceMappingList.bdms_by_instance_uuid')
+ @mock.patch.object(InstanceGroup, 'get_by_instance_uuid')
+ @mock.patch('nova.compute.api.API.update_instance')
+ def test_server_update_with_extra_specs_policy(self,
+ mock_update, mock_group, mock_bdm):
+ mock_update.return_value = self.instance
+ rule = policies.SERVERS % 'update'
+ # server 'update' policy is checked before flavor extra specs
+ # policy so we have to allow it for everyone otherwise it will fail
+ # first for unauthorized contexts.
+ self.policy.set_rules({rule: "@"}, overwrite=False)
+ req = fakes.HTTPRequest.blank('', version='2.47')
+ rule_name = policies.SERVERS % 'show:flavor-extra-specs'
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_reader_authorized_contexts,
+ rule_name, self.controller.update,
+ req, self.instance.uuid,
+ body={'server': {'name': 'test'}},
+ fatal=False)
+ for resp in authorize_res:
+ self.assertIn('extra_specs', resp['server']['flavor'])
+ for resp in unauthorize_res:
+ self.assertNotIn('extra_specs', resp['server']['flavor'])
+
@mock.patch('nova.compute.api.API.create')
def test_create_server_policy(self, mock_create):
mock_create.return_value = ([self.instance], '')
rule_name = policies.SERVERS % 'create'
- self.common_policy_check(self.project_member_authorized_contexts,
- self.project_member_unauthorized_contexts,
- rule_name,
- self.controller.create,
- self.req, body=self.body)
+ self.common_policy_auth(self.project_member_authorized_contexts,
+ rule_name,
+ self.controller.create,
+ self.req, body=self.body)
@mock.patch('nova.compute.api.API.create')
@mock.patch('nova.compute.api.API.parse_availability_zone')
@@ -431,11 +441,10 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
mock_create.return_value = ([self.instance], '')
mock_az.return_value = ('test', 'host', None)
- self.common_policy_check(self.project_admin_authorized_contexts,
- self.project_admin_unauthorized_contexts,
- self.rule_forced_host,
- self.controller.create,
- self.req, body=self.body)
+ self.common_policy_auth(self.all_projects_admin_authorized_contexts,
+ self.rule_forced_host,
+ self.controller.create,
+ self.req, body=self.body)
@mock.patch('nova.compute.api.API.create')
def test_create_attach_volume_server_policy(self, mock_create):
@@ -453,11 +462,10 @@ class ServersPolicyTest(base.BasePolicyTest):
'block_device_mapping': [{'device_name': 'foo'}],
},
}
- self.common_policy_check(self.project_member_authorized_contexts,
- self.project_member_unauthorized_contexts,
- self.rule_attach_volume,
- self.controller.create,
- self.req, body=body)
+ self.common_policy_auth(self.project_member_authorized_contexts,
+ self.rule_attach_volume,
+ self.controller.create,
+ self.req, body=body)
@mock.patch('nova.compute.api.API.create')
def test_create_attach_network_server_policy(self, mock_create):
@@ -477,11 +485,10 @@ class ServersPolicyTest(base.BasePolicyTest):
}],
},
}
- self.common_policy_check(self.project_member_authorized_contexts,
- self.project_member_unauthorized_contexts,
- self.rule_attach_network,
- self.controller.create,
- self.req, body=body)
+ self.common_policy_auth(self.project_member_authorized_contexts,
+ self.rule_attach_network,
+ self.controller.create,
+ self.req, body=body)
@mock.patch('nova.compute.api.API.create')
def test_create_trusted_certs_server_policy(self, mock_create):
@@ -504,20 +511,18 @@ class ServersPolicyTest(base.BasePolicyTest):
},
}
- self.common_policy_check(self.project_member_authorized_contexts,
- self.project_member_unauthorized_contexts,
- self.rule_trusted_certs,
- self.controller.create,
- req, body=body)
+ self.common_policy_auth(self.project_member_authorized_contexts,
+ self.rule_trusted_certs,
+ self.controller.create,
+ req, body=body)
@mock.patch('nova.compute.api.API.delete')
def test_delete_server_policy(self, mock_delete):
rule_name = policies.SERVERS % 'delete'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller.delete,
- self.req, self.instance.uuid)
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller.delete,
+ self.req, self.instance.uuid)
def test_delete_server_policy_failed_with_other_user(self):
# Change the user_id in request context.
@@ -547,11 +552,10 @@ class ServersPolicyTest(base.BasePolicyTest):
rule_name = policies.SERVERS % 'update'
body = {'server': {'name': 'test'}}
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller.update,
- self.req, self.instance.uuid, body=body)
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller.update,
+ self.req, self.instance.uuid, body=body)
def test_update_server_policy_failed_with_other_user(self):
# Change the user_id in request context.
@@ -582,44 +586,40 @@ class ServersPolicyTest(base.BasePolicyTest):
def test_confirm_resize_server_policy(self, mock_confirm_resize):
rule_name = policies.SERVERS % 'confirm_resize'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_confirm_resize,
- self.req, self.instance.uuid,
- body={'confirmResize': 'null'})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._action_confirm_resize,
+ self.req, self.instance.uuid,
+ body={'confirmResize': 'null'})
@mock.patch('nova.compute.api.API.revert_resize')
def test_revert_resize_server_policy(self, mock_revert_resize):
rule_name = policies.SERVERS % 'revert_resize'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_revert_resize,
- self.req, self.instance.uuid,
- body={'revertResize': 'null'})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._action_revert_resize,
+ self.req, self.instance.uuid,
+ body={'revertResize': 'null'})
@mock.patch('nova.compute.api.API.reboot')
def test_reboot_server_policy(self, mock_reboot):
rule_name = policies.SERVERS % 'reboot'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_reboot,
- self.req, self.instance.uuid,
- body={'reboot': {'type': 'soft'}})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._action_reboot,
+ self.req, self.instance.uuid,
+ body={'reboot': {'type': 'soft'}})
@mock.patch('nova.compute.api.API.resize')
def test_resize_server_policy(self, mock_resize):
rule_name = policies.SERVERS % 'resize'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_resize,
- self.req, self.instance.uuid,
- body={'resize': {'flavorRef': 'f1'}})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._action_resize,
+ self.req, self.instance.uuid,
+ body={'resize': {'flavorRef': 'f1'}})
def test_resize_server_policy_failed_with_other_user(self):
# Change the user_id in request context.
@@ -650,23 +650,21 @@ class ServersPolicyTest(base.BasePolicyTest):
def test_start_server_policy(self, mock_start):
rule_name = policies.SERVERS % 'start'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._start_server,
- self.req, self.instance.uuid,
- body={'os-start': 'null'})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._start_server,
+ self.req, self.instance.uuid,
+ body={'os-start': 'null'})
@mock.patch('nova.compute.api.API.stop')
def test_stop_server_policy(self, mock_stop):
rule_name = policies.SERVERS % 'stop'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._stop_server,
- self.req, self.instance.uuid,
- body={'os-stop': 'null'})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._stop_server,
+ self.req, self.instance.uuid,
+ body={'os-stop': 'null'})
def test_stop_server_policy_failed_with_other_user(self):
# Change the user_id in request context.
@@ -696,12 +694,11 @@ class ServersPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.API.rebuild')
def test_rebuild_server_policy(self, mock_rebuild):
rule_name = policies.SERVERS % 'rebuild'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_rebuild,
- self.req, self.instance.uuid,
- body={'rebuild': {"imageRef": uuids.fake_id}})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._action_rebuild,
+ self.req, self.instance.uuid,
+ body={'rebuild': {"imageRef": uuids.fake_id}})
def test_rebuild_server_policy_failed_with_other_user(self):
# Change the user_id in request context.
@@ -743,11 +740,17 @@ class ServersPolicyTest(base.BasePolicyTest):
'trusted_image_certificates': [uuids.fake_id],
},
}
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_rebuild,
- req, self.instance.uuid, body=body)
+
+ if not CONF.oslo_policy.enforce_scope:
+ check_rule = rule_name
+ else:
+ check_rule = functools.partial(
+ base.rule_if_system, rule, rule_name)
+
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ check_rule,
+ self.controller._action_rebuild,
+ req, self.instance.uuid, body=body)
def test_rebuild_trusted_certs_policy_failed_with_other_user(self):
# Change the user_id in request context.
@@ -796,12 +799,11 @@ class ServersPolicyTest(base.BasePolicyTest):
def test_create_image_server_policy(self, mock_snapshot, mock_image,
mock_bdm):
rule_name = policies.SERVERS % 'create_image'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_create_image,
- self.req, self.instance.uuid,
- body={'createImage': {"name": 'test'}})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._action_create_image,
+ self.req, self.instance.uuid,
+ body={'createImage': {"name": 'test'}})
@mock.patch('nova.objects.BlockDeviceMappingList.get_by_instance_uuid')
@mock.patch('nova.image.glance.API.generate_image_url')
@@ -816,23 +818,26 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
rule_name = policies.SERVERS % 'create_image:allow_volume_backed'
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_create_image,
- self.req, self.instance.uuid,
- body={'createImage': {"name": 'test'}})
+ if not CONF.oslo_policy.enforce_scope:
+ check_rule = rule_name
+ else:
+ check_rule = functools.partial(
+ base.rule_if_system, rule, rule_name)
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ check_rule,
+ self.controller._action_create_image,
+ self.req, self.instance.uuid,
+ body={'createImage': {"name": 'test'}})
@mock.patch('nova.compute.api.API.trigger_crash_dump')
def test_trigger_crash_dump_server_policy(self, mock_crash):
rule_name = policies.SERVERS % 'trigger_crash_dump'
req = fakes.HTTPRequest.blank('', version='2.17')
- self.common_policy_check(self.admin_or_owner_authorized_contexts,
- self.admin_or_owner_unauthorized_contexts,
- rule_name,
- self.controller._action_trigger_crash_dump,
- req, self.instance.uuid,
- body={'trigger_crash_dump': None})
+ self.common_policy_auth(self.project_action_authorized_contexts,
+ rule_name,
+ self.controller._action_trigger_crash_dump,
+ req, self.instance.uuid,
+ body={'trigger_crash_dump': None})
def test_trigger_crash_dump_policy_failed_with_other_user(self):
# Change the user_id in request context.
@@ -876,9 +881,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.3')
rule_name = ea_policies.BASE_POLICY_NAME
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.all_projects_admin_authorized_contexts,
rule_name, self.controller.detail, req,
fatal=False)
for attr in self.extended_attr:
@@ -897,9 +901,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.3')
rule_name = ea_policies.BASE_POLICY_NAME
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller.show, req, 'fake',
fatal=False)
for attr in self.extended_attr:
@@ -920,9 +923,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.75')
rule_name = ea_policies.BASE_POLICY_NAME
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller._action_rebuild,
req, self.instance.uuid,
body={'rebuild': {"imageRef": uuids.fake_id}},
@@ -940,8 +942,11 @@ class ServersPolicyTest(base.BasePolicyTest):
@mock.patch('nova.objects.BlockDeviceMappingList.bdms_by_instance_uuid')
@mock.patch.object(InstanceGroup, 'get_by_instance_uuid')
@mock.patch('nova.compute.api.API.update_instance')
+ @mock.patch('nova.compute.api.API.get_instance_host_status')
def test_server_update_with_extended_attr_policy(self,
- mock_update, mock_group, mock_bdm):
+ mock_status, mock_update, mock_group, mock_bdm):
+ mock_update.return_value = self.instance
+ mock_status.return_value = fields.HostStatus.UP
rule = policies.SERVERS % 'update'
# server 'update' policy is checked before extended attributes
# policy so we have to allow it for everyone otherwise it will fail
@@ -949,9 +954,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.75')
rule_name = ea_policies.BASE_POLICY_NAME
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller.update,
req, self.instance.uuid,
body={'server': {'name': 'test'}},
@@ -977,9 +981,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.16')
rule_name = policies.SERVERS % 'show:host_status'
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.all_projects_admin_authorized_contexts,
rule_name, self.controller.detail, req,
fatal=False)
for resp in authorize_res:
@@ -998,9 +1001,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.16')
rule_name = policies.SERVERS % 'show:host_status'
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller.show, req, 'fake',
fatal=False)
for resp in authorize_res:
@@ -1020,9 +1022,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.75')
rule_name = policies.SERVERS % 'show:host_status'
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller._action_rebuild,
req, self.instance.uuid,
body={'rebuild': {"imageRef": uuids.fake_id}},
@@ -1035,8 +1036,11 @@ class ServersPolicyTest(base.BasePolicyTest):
@mock.patch('nova.objects.BlockDeviceMappingList.bdms_by_instance_uuid')
@mock.patch.object(InstanceGroup, 'get_by_instance_uuid')
@mock.patch('nova.compute.api.API.update_instance')
+ @mock.patch('nova.compute.api.API.get_instance_host_status')
def test_server_update_with_host_status_policy(self,
- mock_update, mock_group, mock_bdm):
+ mock_status, mock_update, mock_group, mock_bdm):
+ mock_update.return_value = self.instance
+ mock_status.return_value = fields.HostStatus.UP
rule = policies.SERVERS % 'update'
# server 'update' policy is checked before host_status
# policy so we have to allow it for everyone otherwise it will fail
@@ -1044,9 +1048,8 @@ class ServersPolicyTest(base.BasePolicyTest):
self.policy.set_rules({rule: "@"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.75')
rule_name = policies.SERVERS % 'show:host_status'
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller.update,
req, self.instance.uuid,
body={'server': {'name': 'test'}},
@@ -1079,9 +1082,8 @@ class ServersPolicyTest(base.BasePolicyTest):
rule_host_status: "!"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.16')
rule_name = policies.SERVERS % 'show:host_status:unknown-only'
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.all_projects_admin_authorized_contexts,
rule_name, self.controller.detail, req,
fatal=False)
for resp in authorize_res:
@@ -1107,9 +1109,8 @@ class ServersPolicyTest(base.BasePolicyTest):
rule_host_status: "!"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.16')
rule_name = policies.SERVERS % 'show:host_status:unknown-only'
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller.show, req, 'fake',
fatal=False)
for resp in authorize_res:
@@ -1136,9 +1137,8 @@ class ServersPolicyTest(base.BasePolicyTest):
rule_host_status: "!"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.75')
rule_name = policies.SERVERS % 'show:host_status:unknown-only'
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller._action_rebuild,
req, self.instance.uuid,
body={'rebuild': {"imageRef": uuids.fake_id}},
@@ -1156,6 +1156,7 @@ class ServersPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.API.update_instance')
def test_server_update_with_unknown_host_status_policy(self,
mock_update, mock_group, mock_status, mock_bdm):
+ mock_update.return_value = self.instance
mock_status.return_value = fields.HostStatus.UNKNOWN
rule = policies.SERVERS % 'update'
# server 'update' policy is checked before unknown host_status
@@ -1168,9 +1169,8 @@ class ServersPolicyTest(base.BasePolicyTest):
rule_host_status: "!"}, overwrite=False)
req = fakes.HTTPRequest.blank('', version='2.75')
rule_name = policies.SERVERS % 'show:host_status:unknown-only'
- authorize_res, unauthorize_res = self.common_policy_check(
- self.server_attr_admin_authorized_contexts,
- self.server_attr_admin_unauthorized_contexts,
+ authorize_res, unauthorize_res = self.common_policy_auth(
+ self.project_admin_authorized_contexts,
rule_name, self.controller.update,
req, self.instance.uuid,
body={'server': {'name': 'test'}},
@@ -1194,9 +1194,9 @@ class ServersPolicyTest(base.BasePolicyTest):
def fake_create(context, *args, **kwargs):
for attr in ['requested_host', 'requested_hypervisor_hostname']:
- if context in self.project_admin_authorized_contexts:
+ if context in self.all_projects_admin_authorized_contexts:
self.assertIn(attr, kwargs)
- if context in self.project_admin_unauthorized_contexts:
+ if context not in self.all_projects_admin_authorized_contexts:
self.assertNotIn(attr, kwargs)
return ([self.instance], '')
mock_create.side_effect = fake_create
@@ -1214,11 +1214,10 @@ class ServersPolicyTest(base.BasePolicyTest):
},
}
- self.common_policy_check(self.project_admin_authorized_contexts,
- self.project_admin_unauthorized_contexts,
- self.rule_requested_destination,
- self.controller.create,
- req, body=body)
+ self.common_policy_auth(self.all_projects_admin_authorized_contexts,
+ self.rule_requested_destination,
+ self.controller.create,
+ req, body=body)
@mock.patch(
'nova.servicegroup.api.API.service_is_up',
@@ -1230,10 +1229,9 @@ class ServersPolicyTest(base.BasePolicyTest):
@mock.patch('nova.compute.api.API._allow_resize_to_same_host')
@mock.patch('nova.objects.RequestSpec.get_by_instance_uuid')
@mock.patch('nova.objects.Instance.save')
- @mock.patch('nova.api.openstack.common.get_instance')
@mock.patch('nova.conductor.ComputeTaskAPI.resize_instance')
def test_cross_cell_resize_server_policy(
- self, mock_resize, mock_get, mock_save, mock_rs, mock_allow, m_net
+ self, mock_resize, mock_save, mock_rs, mock_allow, m_net
):
# 'migrate' policy is checked before 'resize:cross_cell' so
@@ -1263,13 +1261,13 @@ class ServersPolicyTest(base.BasePolicyTest):
)
return inst
- mock_get.side_effect = fake_get
+ self.mock_get.side_effect = fake_get
def fake_validate(context, instance,
host_name, allow_cross_cell_resize):
if context in self.cross_cell_authorized_contexts:
self.assertTrue(allow_cross_cell_resize)
- if context in self.cross_cell_unauthorized_contexts:
+ if context not in self.cross_cell_authorized_contexts:
self.assertFalse(allow_cross_cell_resize)
return objects.ComputeNode(host=1, hypervisor_hostname=2)
@@ -1277,23 +1275,24 @@ class ServersPolicyTest(base.BasePolicyTest):
'nova.compute.api.API._validate_host_for_cold_migrate',
fake_validate)
- self.common_policy_check(self.cross_cell_authorized_contexts,
- self.cross_cell_unauthorized_contexts,
- rule_name,
- self.m_controller._migrate,
- req, self.instance.uuid,
- body={'migrate': {'host': 'fake'}},
- fatal=False)
+ self.common_policy_auth(self.cross_cell_authorized_contexts,
+ rule_name,
+ self.m_controller._migrate,
+ req, self.instance.uuid,
+ body={'migrate': {'host': 'fake'}},
+ fatal=False)
def test_network_attach_external_network_policy(self):
# NOTE(gmann): Testing policy 'network:attach_external_network'
# which raise different error then PolicyNotAuthorized
# if not allowed.
neutron_api = neutron.API()
- for context in self.zero_disk_external_net_authorized_contexts:
+ for context in self.all_projects_admin_authorized_contexts:
neutron_api._check_external_network_attach(context,
[{'id': 1, 'router:external': 'ext'}])
- for context in self.zero_disk_external_net_unauthorized_contexts:
+ unauth = (set(self.all_contexts) -
+ set(self.all_projects_admin_authorized_contexts))
+ for context in unauth:
self.assertRaises(exception.ExternalNetworkAttachForbidden,
neutron_api._check_external_network_attach,
context, [{'id': 1, 'router:external': 'ext'}])
@@ -1306,16 +1305,63 @@ class ServersPolicyTest(base.BasePolicyTest):
flavor = objects.Flavor(
vcpus=1, memory_mb=512, root_gb=0, extra_specs={'hw:pmu': "true"})
compute_api = compute.API()
- for context in self.zero_disk_external_net_authorized_contexts:
+ for context in self.all_projects_admin_authorized_contexts:
compute_api._validate_flavor_image_nostatus(context,
image, flavor, None)
- for context in self.zero_disk_external_net_unauthorized_contexts:
+ unauth = (set(self.all_contexts) -
+ set(self.all_projects_admin_authorized_contexts))
+ for context in unauth:
self.assertRaises(
exception.BootFromVolumeRequiredForZeroDiskFlavor,
compute_api._validate_flavor_image_nostatus,
context, image, flavor, None)
+class ServersNoLegacyNoScopeTest(ServersPolicyTest):
+ """Test Servers API policies with deprecated rules disabled, but scope
+ checking still disabled.
+ """
+ without_deprecated_rules = True
+ rules_without_deprecation = {
+ policies.SERVERS % 'show:flavor-extra-specs':
+ base_policy.PROJECT_READER_OR_ADMIN,
+ }
+
+ def setUp(self):
+ super(ServersNoLegacyNoScopeTest, self).setUp()
+
+ # Disabling legacy rule support means that we no longer allow
+ # random roles on our project to take action on our
+ # resources. Legacy admin will have access.
+ self.project_action_authorized_contexts = (
+ self.project_member_or_admin_with_no_scope_no_legacy)
+
+ # The only additional role that can read our resources is our
+ # own project_reader.
+ self.project_reader_authorized_contexts = (
+ self.project_reader_or_admin_with_no_scope_no_legacy)
+
+ # Disabling legacy support means random roles lose power to
+ # see everything in their project.
+ self.reduce_set('everyone_authorized',
+ self.all_contexts - set([self.project_foo_context,
+ self.system_foo_context]))
+
+ # Disabling legacy support means readers and random roles lose
+ # power to create things on their own projects. Note that
+ # system_admin and system_member are still here because we are
+ # not rejecting them by scope, even though these operations
+ # with those tokens are likely to fail because they have no
+ # project.
+ self.reduce_set('project_member_authorized',
+ self.all_contexts - set([
+ self.system_reader_context,
+ self.system_foo_context,
+ self.project_reader_context,
+ self.project_foo_context,
+ self.other_project_reader_context]))
+
+
class ServersScopeTypePolicyTest(ServersPolicyTest):
"""Test Servers APIs policies with system scope enabled.
This class set the nova.conf [oslo_policy] enforce_scope to True
@@ -1342,143 +1388,77 @@ class ServersScopeTypePolicyTest(ServersPolicyTest):
self.rule_requested_destination = None
self.rule_forced_host = None
- # Check that system admin is able to create server with host request
- # and get server extended attributes or host status.
- self.admin_authorized_contexts = [
- self.system_admin_context
- ]
- # Check that non-system/admin is not able to create server with
- # host request and get server extended attributes or host status.
- self.admin_unauthorized_contexts = [
- self.project_admin_context, self.legacy_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
- ]
- # Check that system reader is able to list the server
- # for all projects.
- self.system_reader_authorized_contexts = [
- self.system_admin_context, self.system_member_context,
- self.system_reader_context]
- # Check that non-system reader is not able to list the server
- # for all projects.
- self.system_reader_unauthorized_contexts = [
- self.legacy_admin_context, self.project_admin_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
- ]
-
- # Check if project member can create the server.
- self.project_member_authorized_contexts = [
- self.legacy_admin_context,
- self.project_admin_context, self.project_member_context,
- self.other_project_member_context,
- self.project_reader_context, self.project_foo_context,
- self.other_project_reader_context
- ]
- # Check if non-project member cannot create the server.
- self.project_member_unauthorized_contexts = [
- self.system_admin_context, self.system_member_context,
- self.system_reader_context, self.system_foo_context
- ]
-
- # Check that project admin is able to create server with requested
- # destination.
- self.project_admin_authorized_contexts = [
- self.legacy_admin_context, self.project_admin_context]
- # Check that non-project admin is not able to create server with
- # requested destination
- self.project_admin_unauthorized_contexts = [
- self.system_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
- ]
+ # With scope checking enabled, system admins no longer have
+ # admin-granted project resource access.
+ self.reduce_set('project_action_authorized',
+ set([self.legacy_admin_context,
+ self.project_admin_context,
+ self.project_member_context,
+ self.project_reader_context,
+ self.project_foo_context]))
+
+ # No change from the base behavior here, but we need to
+ # re-build this from project_action_authorized, since we
+ # changed it above.
+ self.project_reader_authorized_contexts = (
+ self.project_action_authorized_contexts)
+
+ # With scope checking enabled, system users no longer have
+ # project access, even to create their own resources.
+ self.reduce_set('project_member_authorized', self.all_project_contexts)
+
+ # With scope checking enabled, system admin is no longer an
+ # admin of project resources.
+ self.reduce_set('project_admin_authorized',
+ set([self.legacy_admin_context,
+ self.project_admin_context]))
+ self.reduce_set('all_projects_admin_authorized',
+ set([self.legacy_admin_context,
+ self.project_admin_context]))
+
+ # With scope checking enabled, system users also lose access to read
+ # project resources.
+ self.reduce_set('everyone_authorized',
+ self.all_contexts - self.all_system_contexts)
class ServersNoLegacyPolicyTest(ServersScopeTypePolicyTest):
"""Test Servers APIs policies with system scope enabled,
- and no more deprecated rules that allow the legacy admin API to
- access system_admin_or_owner APIs.
+ and no more deprecated rules.
"""
without_deprecated_rules = True
+ rules_without_deprecation = {
+ policies.SERVERS % 'show:flavor-extra-specs':
+ base_policy.PROJECT_READER_OR_ADMIN,
+ }
def setUp(self):
super(ServersNoLegacyPolicyTest, self).setUp()
- # Check that system admin or owner is able to update, delete
- # or perform server action.
- self.admin_or_owner_authorized_contexts = [
- self.system_admin_context,
- self.project_admin_context, self.project_member_context,
- ]
- # Check that non-system and non-admin/owner is not able to update,
- # delete or perform server action.
- self.admin_or_owner_unauthorized_contexts = [
- self.legacy_admin_context, self.system_member_context,
- self.system_reader_context, self.project_reader_context,
- self.project_foo_context,
- self.system_foo_context, self.other_project_member_context,
- self.other_project_reader_context]
-
- # Check that system reader or projct owner is able to get
- # server.
- self.system_reader_or_owner_authorized_contexts = [
- self.system_admin_context,
- self.project_admin_context, self.system_member_context,
- self.system_reader_context, self.project_reader_context,
- self.project_member_context,
- ]
-
- # Check that non-system reader nd non-admin/owner is not able to get
- # server.
- self.system_reader_or_owner_unauthorized_contexts = [
- self.legacy_admin_context, self.project_foo_context,
- self.system_foo_context, self.other_project_member_context,
- self.other_project_reader_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.other_project_reader_context,
- ]
- self.everyone_unauthorized_contexts = [
- self.project_foo_context,
- self.system_foo_context
- ]
- # Check if project member can create the server.
- 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.
- self.project_member_unauthorized_contexts = [
- self.system_admin_context,
- self.system_member_context, self.project_reader_context,
- self.project_foo_context, self.other_project_reader_context,
- self.system_reader_context, self.system_foo_context
- ]
- # Check that system admin is able to get server extended attributes
- # or host status.
- self.server_attr_admin_authorized_contexts = [
- self.system_admin_context]
- # Check that non-system admin is not able to get server extended
- # attributes or host status.
- self.server_attr_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
- ]
+ # Disabling legacy support means legacy_admin is no longer
+ # powerful on our project. Also, we drop the "any role on the
+ # project means you can do stuff" behavior, so project_reader
+ # and project_foo lose power.
+ self.project_action_authorized_contexts = (
+ self.project_member_or_admin_with_scope_no_legacy)
+
+ # Only project_reader has additional read access to our
+ # project resources.
+ self.project_reader_authorized_contexts = (
+ self.project_action_authorized_contexts |
+ set([self.project_reader_context]))
+
+ # Disabling legacy support means random roles lose power to
+ # see everything in their project.
+ self.reduce_set(
+ 'everyone_authorized',
+ self.all_project_contexts - set([self.project_foo_context]))
+
+ # Disabling legacy support means readers and random roles lose
+ # power to create things on their own projects.
+ self.reduce_set('project_member_authorized',
+ self.all_project_contexts - set([
+ self.project_foo_context,
+ self.project_reader_context,
+ self.other_project_reader_context,
+ ]))