Enable new defaults and scope checks by default
As discussed in PTG, we need to test the new RBAC in the integrated gate and accordingly enable the new defaults and scope check by default. A new integrated testing job has been added and results show that the new defaults and scope checks are working fine. During testing, we found a few bugs in neutron policies but all are fixed now. enforce_scope and enforce_new_defaults are oslo policy config options but they are per service level and the default value can be overridden. Oslo policy 3.11.0 version allows to override the default value for these config options[1] so upgrading the oslo policy version in requirements.txt Depends-On: https://review.opendev.org/c/openstack/devstack/+/869781 Depends-On: https://review.opendev.org/c/openstack/placement/+/869525 [1] https://github.com/openstack/oslo.policy/blob/3.11.0/oslo_policy/opts.py#L125 Change-Id: I977b2daedf880229c8d364ca011f2ea965b86e3a
This commit is contained in:
parent
5e5b6751d3
commit
d97af33c06
34
.zuul.yaml
34
.zuul.yaml
@ -665,6 +665,36 @@
|
||||
parent: tempest-integrated-compute
|
||||
nodeset: openstack-single-node-focal
|
||||
|
||||
# TODO(gmann): Remove this jobs once all the required services for intergrate
|
||||
# compute gate (Cinder, Glance, Neutron) by default enable scope and new
|
||||
# defaults which means all the nova jobs will be tested with new RBAC in
|
||||
# integrated way and we do not need this separate job.
|
||||
- job:
|
||||
name: tempest-integrated-compute-enforce-scope-new-defaults
|
||||
parent: tempest-integrated-compute
|
||||
description: |
|
||||
This job runs the Tempest tests with scope and new defaults enabled
|
||||
for Nova, Neutron, Glance, and Cinder services.
|
||||
# TODO (gmann): There were few fixes in neutron and neutron-lib for the
|
||||
# RBAC but they are not yet released so we need to add both projcts as
|
||||
# the required-projects. Those can be removed once new version of neutron
|
||||
# and neutron-lib is released.
|
||||
required-projects:
|
||||
- openstack/neutron
|
||||
- openstack/neutron-lib
|
||||
vars:
|
||||
devstack_localrc:
|
||||
# Enabeling the scope and new defaults for services implemented it.
|
||||
# NOTE (gmann): We need to keep keystone scope check disable as
|
||||
# services (except ironic) does not support the system scope and
|
||||
# they need keystone to continue working with project scope. Until
|
||||
# Keystone policies are changed to work for project scoped also, we
|
||||
# need to keep scope check disable for keystone.
|
||||
NOVA_ENFORCE_SCOPE: true
|
||||
CINDER_ENFORCE_SCOPE: true
|
||||
GLANCE_ENFORCE_SCOPE: true
|
||||
NEUTRON_ENFORCE_SCOPE: true
|
||||
|
||||
- project:
|
||||
# Please try to keep the list of job names sorted alphabetically.
|
||||
templates:
|
||||
@ -723,6 +753,8 @@
|
||||
- ^tox.ini$
|
||||
- tempest-integrated-compute-ubuntu-focal:
|
||||
irrelevant-files: *policies-irrelevant-files
|
||||
- tempest-integrated-compute-enforce-scope-new-defaults:
|
||||
irrelevant-files: *policies-irrelevant-files
|
||||
- grenade-skip-level:
|
||||
irrelevant-files: *policies-irrelevant-files
|
||||
- nova-grenade-multinode:
|
||||
@ -758,6 +790,8 @@
|
||||
irrelevant-files: *policies-irrelevant-files
|
||||
- tempest-integrated-compute-ubuntu-focal:
|
||||
irrelevant-files: *policies-irrelevant-files
|
||||
- tempest-integrated-compute-enforce-scope-new-defaults:
|
||||
irrelevant-files: *policies-irrelevant-files
|
||||
- nova-grenade-multinode:
|
||||
irrelevant-files: *policies-irrelevant-files
|
||||
- tempest-ipv6-only:
|
||||
|
@ -41,11 +41,15 @@ USER_BASED_RESOURCES = ['os-keypairs']
|
||||
saved_file_rules = []
|
||||
KEY_EXPR = re.compile(r'%\((\w+)\)s')
|
||||
|
||||
# TODO(gmann): Remove setting the default value of config policy_file
|
||||
# once oslo_policy change the default value to 'policy.yaml'.
|
||||
# https://github.com/openstack/oslo.policy/blob/a626ad12fe5a3abd49d70e3e5b95589d279ab578/oslo_policy/opts.py#L49
|
||||
# TODO(gmann): Remove overriding the default value of config options
|
||||
# 'policy_file', 'enforce_scope', and 'enforce_new_defaults' once
|
||||
# oslo_policy change their default value to what is overridden here.
|
||||
DEFAULT_POLICY_FILE = 'policy.yaml'
|
||||
opts.set_defaults(cfg.CONF, DEFAULT_POLICY_FILE)
|
||||
opts.set_defaults(
|
||||
cfg.CONF,
|
||||
DEFAULT_POLICY_FILE,
|
||||
enforce_scope=True,
|
||||
enforce_new_defaults=True)
|
||||
|
||||
|
||||
def reset():
|
||||
|
@ -87,7 +87,8 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super(ServerGroupTestV21, self).setUp()
|
||||
self._setup_controller()
|
||||
self.req = fakes.HTTPRequest.blank('')
|
||||
self.member_req = fakes.HTTPRequest.member_req('')
|
||||
self.reader_req = fakes.HTTPRequest.reader_req('')
|
||||
self.admin_req = fakes.HTTPRequest.blank('', use_admin_context=True)
|
||||
self.foo_req = fakes.HTTPRequest.blank('', project_id='foo')
|
||||
self.policy = self.useFixture(fixtures.RealPolicyFixture())
|
||||
@ -114,20 +115,20 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
def test_create_server_group_with_no_policies(self):
|
||||
sgroup = server_group_template()
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
def _create_server_group_normal(self, policies=None, policy=None,
|
||||
rules=None):
|
||||
sgroup = server_group_template()
|
||||
sgroup['policies'] = policies
|
||||
res_dict = self.controller.create(self.req,
|
||||
res_dict = self.controller.create(self.member_req,
|
||||
body={'server_group': sgroup})
|
||||
self.assertEqual(res_dict['server_group']['name'], 'test')
|
||||
self.assertTrue(uuidutils.is_uuid_like(res_dict['server_group']['id']))
|
||||
self.assertEqual(res_dict['server_group']['policies'], policies)
|
||||
|
||||
def test_create_server_group_with_new_policy_before_264(self):
|
||||
req = fakes.HTTPRequest.blank('', version='2.63')
|
||||
req = fakes.HTTPRequest.member_req('', version='2.63')
|
||||
policy = 'anti-affinity'
|
||||
rules = {'max_server_per_host': 3}
|
||||
# 'policy' isn't an acceptable request key before 2.64
|
||||
@ -162,7 +163,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
self.controller.create(self.admin_req, body={'server_group': sgroup})
|
||||
|
||||
# test as non-admin
|
||||
self.controller.create(self.req, body={'server_group': sgroup})
|
||||
self.controller.create(self.member_req, body={'server_group': sgroup})
|
||||
|
||||
def _create_instance(self, ctx, cell):
|
||||
with context.target_cell(ctx, cell) as cctx:
|
||||
@ -289,7 +290,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
path = path or '/os-server-groups?all_projects=True'
|
||||
if limited:
|
||||
path += limited
|
||||
req = fakes.HTTPRequest.blank(path, version=api_version)
|
||||
reader_req = fakes.HTTPRequest.reader_req(path, version=api_version)
|
||||
admin_req = fakes.HTTPRequest.blank(path, use_admin_context=True,
|
||||
version=api_version)
|
||||
|
||||
@ -298,7 +299,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
self.assertEqual(all, res_dict)
|
||||
|
||||
# test as non-admin
|
||||
res_dict = self.controller.index(req)
|
||||
res_dict = self.controller.index(reader_req)
|
||||
self.assertEqual(tenant_specific, res_dict)
|
||||
|
||||
@mock.patch('nova.objects.InstanceGroupList.get_by_project_id')
|
||||
@ -347,25 +348,27 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
return_get_by_project = return_server_groups()
|
||||
mock_get_by_project.return_value = return_get_by_project
|
||||
path = '/os-server-groups'
|
||||
req = fakes.HTTPRequest.blank(path, version=api_version)
|
||||
req = fakes.HTTPRequest.reader_req(path, version=api_version)
|
||||
res_dict = self.controller.index(req)
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_display_members(self):
|
||||
ctx = context.RequestContext('fake_user', fakes.FAKE_PROJECT_ID)
|
||||
(ig_uuid, instances, members) = self._create_groups_and_instances(ctx)
|
||||
res_dict = self.controller.show(self.req, ig_uuid)
|
||||
res_dict = self.controller.show(self.reader_req, ig_uuid)
|
||||
result_members = res_dict['server_group']['members']
|
||||
self.assertEqual(3, len(result_members))
|
||||
for member in members:
|
||||
self.assertIn(member, result_members)
|
||||
|
||||
def test_display_members_with_nonexistent_group(self):
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show, self.req, uuidsentinel.group)
|
||||
self.assertRaises(
|
||||
webob.exc.HTTPNotFound,
|
||||
self.controller.show, self.reader_req, uuidsentinel.group)
|
||||
|
||||
def test_display_active_members_only(self):
|
||||
ctx = context.RequestContext('fake_user', fakes.FAKE_PROJECT_ID)
|
||||
ctx = context.RequestContext('fake_user', fakes.FAKE_PROJECT_ID,
|
||||
roles=['member', 'reader'])
|
||||
(ig_uuid, instances, members) = self._create_groups_and_instances(ctx)
|
||||
|
||||
# delete an instance
|
||||
@ -379,7 +382,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
self.assertRaises(exception.InstanceNotFound,
|
||||
objects.Instance.get_by_uuid,
|
||||
ctx, instances[1].uuid)
|
||||
res_dict = self.controller.show(self.req, ig_uuid)
|
||||
res_dict = self.controller.show(self.reader_req, ig_uuid)
|
||||
result_members = res_dict['server_group']['members']
|
||||
# check that only the active instance is displayed
|
||||
self.assertEqual(2, len(result_members))
|
||||
@ -393,7 +396,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
self.controller.show(self.admin_req, ig_uuid)
|
||||
|
||||
# test as non-admin, same project
|
||||
self.controller.show(self.req, ig_uuid)
|
||||
self.controller.show(self.reader_req, ig_uuid)
|
||||
|
||||
# test as non-admin, different project
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
@ -406,7 +409,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
|
||||
sgroup = server_group_template(name='good* $%name',
|
||||
policies=['affinity'])
|
||||
res_dict = self.controller.create(self.req,
|
||||
res_dict = self.controller.create(self.member_req,
|
||||
body={'server_group': sgroup})
|
||||
self.assertEqual(res_dict['server_group']['name'], 'good* $%name')
|
||||
|
||||
@ -414,99 +417,99 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
# blank name
|
||||
sgroup = server_group_template(name='', policies=['test_policy'])
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# name with length 256
|
||||
sgroup = server_group_template(name='1234567890' * 26,
|
||||
policies=['test_policy'])
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# non-string name
|
||||
sgroup = server_group_template(name=12, policies=['test_policy'])
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# name with leading spaces
|
||||
sgroup = server_group_template(name=' leading spaces',
|
||||
policies=['test_policy'])
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# name with trailing spaces
|
||||
sgroup = server_group_template(name='trailing space ',
|
||||
policies=['test_policy'])
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# name with all spaces
|
||||
sgroup = server_group_template(name=' ',
|
||||
policies=['test_policy'])
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# name with unprintable character
|
||||
sgroup = server_group_template(name='bad\x00name',
|
||||
policies=['test_policy'])
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# name with out of range char U0001F4A9
|
||||
sgroup = server_group_template(name=u"\U0001F4A9",
|
||||
policies=['affinity'])
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
def test_create_server_group_with_illegal_policies(self):
|
||||
# blank policy
|
||||
sgroup = server_group_template(name='fake-name', policies='')
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# policy as integer
|
||||
sgroup = server_group_template(name='fake-name', policies=7)
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# policy as string
|
||||
sgroup = server_group_template(name='fake-name', policies='invalid')
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
# policy as None
|
||||
sgroup = server_group_template(name='fake-name', policies=None)
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
def test_create_server_group_conflicting_policies(self):
|
||||
sgroup = server_group_template()
|
||||
policies = ['anti-affinity', 'affinity']
|
||||
sgroup['policies'] = policies
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
def test_create_server_group_with_duplicate_policies(self):
|
||||
sgroup = server_group_template()
|
||||
policies = ['affinity', 'affinity']
|
||||
sgroup['policies'] = policies
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
def test_create_server_group_not_supported(self):
|
||||
sgroup = server_group_template()
|
||||
policies = ['storage-affinity', 'anti-affinity', 'rack-affinity']
|
||||
sgroup['policies'] = policies
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
self.req, body={'server_group': sgroup})
|
||||
self.member_req, body={'server_group': sgroup})
|
||||
|
||||
def test_create_server_group_with_no_body(self):
|
||||
self.assertRaises(self.validation_error,
|
||||
self.controller.create, self.req, body=None)
|
||||
self.controller.create, self.member_req, body=None)
|
||||
|
||||
def test_create_server_group_with_no_server_group(self):
|
||||
body = {'no-instanceGroup': None}
|
||||
self.assertRaises(self.validation_error,
|
||||
self.controller.create, self.req, body=body)
|
||||
self.controller.create, self.member_req, body=body)
|
||||
|
||||
def test_list_server_group_by_tenant(self):
|
||||
self._test_list_server_group_by_tenant(
|
||||
@ -528,7 +531,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
self.controller.index(self.admin_req)
|
||||
|
||||
# test as non-admin
|
||||
self.controller.index(self.req)
|
||||
self.controller.index(self.reader_req)
|
||||
|
||||
def test_list_server_group_multiple_param(self):
|
||||
self._test_list_server_group(api_version=self.wsgi_api_version,
|
||||
@ -598,7 +601,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
self.stub_out('nova.objects.InstanceGroup.get_by_uuid',
|
||||
return_server_group)
|
||||
|
||||
resp = self.controller.delete(self.req, uuidsentinel.sg1_id)
|
||||
resp = self.controller.delete(self.member_req, uuidsentinel.sg1_id)
|
||||
mock_destroy.assert_called_once_with()
|
||||
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
@ -611,7 +614,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
|
||||
def test_delete_non_existing_server_group(self):
|
||||
self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete,
|
||||
self.req, 'invalid')
|
||||
self.member_req, 'invalid')
|
||||
|
||||
def test_delete_server_group_rbac_default(self):
|
||||
ctx = context.RequestContext('fake_user', fakes.FAKE_PROJECT_ID)
|
||||
@ -622,7 +625,7 @@ class ServerGroupTestV21(test.NoDBTestCase):
|
||||
|
||||
# test as non-admin
|
||||
ig_uuid = self._create_groups_and_instances(ctx)[0]
|
||||
self.controller.delete(self.req, ig_uuid)
|
||||
self.controller.delete(self.member_req, ig_uuid)
|
||||
|
||||
|
||||
class ServerGroupTestV213(ServerGroupTestV21):
|
||||
@ -649,7 +652,7 @@ class ServerGroupTestV264(ServerGroupTestV213):
|
||||
|
||||
def _create_server_group_normal(self, policies=None, policy=None,
|
||||
rules=None):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.member_req('', version=self.wsgi_api_version)
|
||||
sgroup = server_group_template()
|
||||
sgroup['rules'] = rules or {}
|
||||
sgroup['policy'] = policy
|
||||
@ -674,7 +677,7 @@ class ServerGroupTestV264(ServerGroupTestV213):
|
||||
self.assertEqual(res_dict['server_group']['rules'], {})
|
||||
|
||||
def _display_server_group(self, uuid):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.reader_req('', version=self.wsgi_api_version)
|
||||
group = self.controller.show(req, uuid)
|
||||
return group
|
||||
|
||||
@ -690,7 +693,7 @@ class ServerGroupTestV264(ServerGroupTestV213):
|
||||
self.assertEqual(res_dict['server_group']['rules'], rules)
|
||||
|
||||
def test_create_affinity_server_group_with_invalid_policy(self):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.member_req('', version=self.wsgi_api_version)
|
||||
sgroup = server_group_template(policy='affinity',
|
||||
rules={'max_server_per_host': 3})
|
||||
result = self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
@ -698,7 +701,7 @@ class ServerGroupTestV264(ServerGroupTestV213):
|
||||
self.assertIn("Only anti-affinity policy supports rules", str(result))
|
||||
|
||||
def test_create_anti_affinity_server_group_with_invalid_rules(self):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.member_req('', version=self.wsgi_api_version)
|
||||
# A negative test for key is unknown, the value is not positive
|
||||
# and not integer
|
||||
invalid_rules = [{'unknown_key': '3'},
|
||||
@ -718,7 +721,7 @@ class ServerGroupTestV264(ServerGroupTestV213):
|
||||
return_value=32)
|
||||
def test_create_server_group_with_low_version_compute_service(self,
|
||||
mock_get_v):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.member_req('', version=self.wsgi_api_version)
|
||||
sgroup = server_group_template(policy='anti-affinity',
|
||||
rules={'max_server_per_host': 3})
|
||||
result = self.assertRaises(
|
||||
@ -734,7 +737,7 @@ class ServerGroupTestV264(ServerGroupTestV213):
|
||||
self._create_server_group_normal(policy=policy)
|
||||
|
||||
def test_policies_since_264(self):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.member_req('', version=self.wsgi_api_version)
|
||||
# 'policies' isn't allowed in request >= 2.64
|
||||
sgroup = server_group_template(policies=['anti-affinity'])
|
||||
self.assertRaises(
|
||||
@ -742,14 +745,14 @@ class ServerGroupTestV264(ServerGroupTestV213):
|
||||
req, body={'server_group': sgroup})
|
||||
|
||||
def test_create_server_group_without_policy(self):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.member_req('', version=self.wsgi_api_version)
|
||||
# 'policy' is required request key in request >= 2.64
|
||||
sgroup = server_group_template()
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
req, body={'server_group': sgroup})
|
||||
|
||||
def test_create_server_group_with_illegal_policies(self):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.member_req('', version=self.wsgi_api_version)
|
||||
# blank policy
|
||||
sgroup = server_group_template(policy='')
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
@ -771,7 +774,7 @@ class ServerGroupTestV264(ServerGroupTestV213):
|
||||
req, body={'server_group': sgroup})
|
||||
|
||||
def test_additional_params(self):
|
||||
req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.member_req('', version=self.wsgi_api_version)
|
||||
sgroup = server_group_template(unknown='unknown')
|
||||
self.assertRaises(self.validation_error, self.controller.create,
|
||||
req, body={'server_group': sgroup})
|
||||
@ -786,7 +789,7 @@ class ServerGroupTestV275(ServerGroupTestV264):
|
||||
path='/os-server-groups?dummy=False&all_projects=True')
|
||||
|
||||
def test_list_server_group_additional_param(self):
|
||||
req = fakes.HTTPRequest.blank('/os-server-groups?dummy=False',
|
||||
version=self.wsgi_api_version)
|
||||
req = fakes.HTTPRequest.reader_req('/os-server-groups?dummy=False',
|
||||
version=self.wsgi_api_version)
|
||||
self.assertRaises(self.validation_error, self.controller.index,
|
||||
req)
|
||||
|
@ -240,6 +240,9 @@ class HTTPRequest(os_wsgi.Request):
|
||||
def blank(cls, *args, **kwargs):
|
||||
defaults = {'base_url': 'http://localhost/v2'}
|
||||
use_admin_context = kwargs.pop('use_admin_context', False)
|
||||
roles = kwargs.pop('roles', [])
|
||||
if use_admin_context:
|
||||
roles.append('admin')
|
||||
project_id = kwargs.pop('project_id', FAKE_PROJECT_ID)
|
||||
version = kwargs.pop('version', os_wsgi.DEFAULT_API_VERSION)
|
||||
defaults.update(kwargs)
|
||||
@ -247,10 +250,19 @@ class HTTPRequest(os_wsgi.Request):
|
||||
out.environ['nova.context'] = FakeRequestContext(
|
||||
user_id='fake_user',
|
||||
project_id=project_id,
|
||||
is_admin=use_admin_context)
|
||||
is_admin=use_admin_context,
|
||||
roles=roles)
|
||||
out.api_version_request = api_version.APIVersionRequest(version)
|
||||
return out
|
||||
|
||||
@classmethod
|
||||
def member_req(cls, *args, **kwargs):
|
||||
return cls.blank(*args, roles=['member', 'reader'], **kwargs)
|
||||
|
||||
@classmethod
|
||||
def reader_req(cls, *args, **kwargs):
|
||||
return cls.blank(*args, roles=['reader'], **kwargs)
|
||||
|
||||
|
||||
class HTTPRequestV21(HTTPRequest):
|
||||
pass
|
||||
|
@ -128,20 +128,21 @@ class TestPolicyCheck(test.NoDBTestCase):
|
||||
self.assertEqual(set(expected_rules), set(passing_rules))
|
||||
|
||||
def test_filter_rules_non_admin(self):
|
||||
context = nova_context.RequestContext()
|
||||
context = nova_context.RequestContext(roles=['reader'])
|
||||
rule_conditions = [base_policies.PROJECT_READER_OR_ADMIN]
|
||||
expected_rules = [r.name for r in ia_policies.list_rules() if
|
||||
r.check_str in rule_conditions]
|
||||
self._check_filter_rules(context, expected_rules=expected_rules)
|
||||
|
||||
def test_filter_rules_admin(self):
|
||||
self._check_filter_rules()
|
||||
context = nova_context.RequestContext(roles=['admin'])
|
||||
self._check_filter_rules(context)
|
||||
|
||||
def test_filter_rules_instance_non_admin(self):
|
||||
db_context = nova_context.RequestContext(user_id='fake-user',
|
||||
project_id='fake-project')
|
||||
instance = fake_instance.fake_instance_obj(db_context)
|
||||
context = nova_context.RequestContext()
|
||||
context = nova_context.RequestContext(roles=['reader'])
|
||||
expected_rules = [r.name for r in ia_policies.list_rules() if
|
||||
r.check_str == base_policies.RULE_ANY]
|
||||
self._check_filter_rules(context, instance, expected_rules)
|
||||
@ -150,11 +151,13 @@ class TestPolicyCheck(test.NoDBTestCase):
|
||||
db_context = nova_context.RequestContext(user_id='fake-user',
|
||||
project_id='fake-project')
|
||||
instance = fake_instance.fake_instance_obj(db_context)
|
||||
self._check_filter_rules(target=instance)
|
||||
context = nova_context.RequestContext(roles=['admin'])
|
||||
self._check_filter_rules(context, target=instance)
|
||||
|
||||
def test_filter_rules_instance_owner(self):
|
||||
db_context = nova_context.RequestContext(user_id='fake-user',
|
||||
project_id='fake-project')
|
||||
project_id='fake-project',
|
||||
roles=['reader'])
|
||||
instance = fake_instance.fake_instance_obj(db_context)
|
||||
rule_conditions = [base_policies.PROJECT_READER_OR_ADMIN]
|
||||
expected_rules = [r.name for r in ia_policies.list_rules() if
|
||||
|
@ -58,6 +58,16 @@ class BasePolicyTest(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(BasePolicyTest, self).setUp()
|
||||
# TODO(gmann): enforce_scope and enforce_new_defaults are enabled
|
||||
# by default in the code so disable them in base test class until
|
||||
# we have deprecated rules and their tests. We have enforce_scope
|
||||
# and no-legacy tests which are explicitly enabling scope and new
|
||||
# defaults to test the new defaults and scope. In future, once
|
||||
# we remove the deprecated rules, along with refactoring the unit
|
||||
# tests we can remove overriding the oslo policy flags.
|
||||
self.flags(enforce_scope=False, group="oslo_policy")
|
||||
if not self.without_deprecated_rules:
|
||||
self.flags(enforce_new_defaults=False, group="oslo_policy")
|
||||
self.useFixture(fixtures.NeutronFixture(self))
|
||||
self.policy = self.useFixture(fixtures.RealPolicyFixture())
|
||||
|
||||
|
@ -303,10 +303,10 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super(RealRolePolicyTestCase, self).setUp()
|
||||
self.policy = self.useFixture(nova_fixtures.RealPolicyFixture())
|
||||
self.non_admin_context = context.RequestContext('fake', 'fake',
|
||||
roles=['member'])
|
||||
self.admin_context = context.RequestContext('fake', 'fake', True,
|
||||
roles=['admin', 'member'])
|
||||
self.non_admin_context = context.RequestContext(
|
||||
'fake', 'fake', roles=['member', 'reader'])
|
||||
self.admin_context = context.RequestContext(
|
||||
'fake', 'fake', True, roles=['admin', 'member', 'reader'])
|
||||
self.target = {}
|
||||
self.fake_policy = jsonutils.loads(fake_policy.policy_data)
|
||||
|
||||
@ -387,6 +387,7 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
|
||||
"os_compute_api:os-hypervisors:search",
|
||||
"os_compute_api:os-hypervisors:servers",
|
||||
"os_compute_api:limits:other_project",
|
||||
"os_compute_api:os-flavor-access",
|
||||
)
|
||||
|
||||
self.admin_or_owner_rules = (
|
||||
@ -440,7 +441,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
|
||||
"os_compute_api:os-remote-consoles",
|
||||
"os_compute_api:os-deferred-delete:restore",
|
||||
"os_compute_api:os-deferred-delete:force",
|
||||
"os_compute_api:os-flavor-access",
|
||||
"os_compute_api:os-flavor-extra-specs:index",
|
||||
"os_compute_api:os-flavor-extra-specs:show",
|
||||
"os_compute_api:os-floating-ips:add",
|
||||
|
@ -0,0 +1,23 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The Nova service enable the API policies (RBAC) new defaults and scope by
|
||||
default. The Default value of config options ``[oslo_policy] enforce_scope``
|
||||
and ``[oslo_policy] oslo_policy.enforce_new_defaults`` have been changed
|
||||
to ``True``.
|
||||
|
||||
This means if you are using system scope token to access Nova API then
|
||||
the request will be failed with 403 error code. Also, new defaults will be
|
||||
enforced by default. To know about the new defaults of each policy
|
||||
rule, refer to the `Policy New Defaults`_. For more detail about the Nova
|
||||
API policies changes, refer to `Policy Concepts`_.
|
||||
|
||||
If you want to disable them then modify the below config options value in
|
||||
``nova.conf`` file::
|
||||
|
||||
[oslo_policy]
|
||||
enforce_new_defaults=False
|
||||
enforce_scope=False
|
||||
|
||||
.. _`Policy New Defaults`: https://docs.openstack.org/nova/latest/configuration/policy.html
|
||||
.. _`Policy Concepts`: https://docs.openstack.org/nova/latest/configuration/policy-concepts.html
|
@ -43,7 +43,7 @@ oslo.utils>=4.12.1 # Apache-2.0
|
||||
oslo.db>=10.0.0 # Apache-2.0
|
||||
oslo.rootwrap>=5.15.0 # Apache-2.0
|
||||
oslo.messaging>=10.3.0 # Apache-2.0
|
||||
oslo.policy>=3.7.0 # Apache-2.0
|
||||
oslo.policy>=3.11.0 # Apache-2.0
|
||||
oslo.privsep>=2.6.2 # Apache-2.0
|
||||
oslo.i18n>=5.1.0 # Apache-2.0
|
||||
oslo.service>=2.8.0 # Apache-2.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user