diff --git a/.zuul.yaml b/.zuul.yaml index 1a35975d3aba..25d6cc6819b5 100644 --- a/.zuul.yaml +++ b/.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: diff --git a/nova/policy.py b/nova/policy.py index 55455a9271dc..c66489cc8d20 100644 --- a/nova/policy.py +++ b/nova/policy.py @@ -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(): diff --git a/nova/tests/unit/api/openstack/compute/test_server_groups.py b/nova/tests/unit/api/openstack/compute/test_server_groups.py index 636682a6b7bb..9d99c3ae6de8 100644 --- a/nova/tests/unit/api/openstack/compute/test_server_groups.py +++ b/nova/tests/unit/api/openstack/compute/test_server_groups.py @@ -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) diff --git a/nova/tests/unit/api/openstack/fakes.py b/nova/tests/unit/api/openstack/fakes.py index 8cf90ddebe20..9ac970f7875f 100644 --- a/nova/tests/unit/api/openstack/fakes.py +++ b/nova/tests/unit/api/openstack/fakes.py @@ -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 diff --git a/nova/tests/unit/cmd/test_policy.py b/nova/tests/unit/cmd/test_policy.py index df51665959f4..29dd5610f674 100644 --- a/nova/tests/unit/cmd/test_policy.py +++ b/nova/tests/unit/cmd/test_policy.py @@ -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 diff --git a/nova/tests/unit/policies/base.py b/nova/tests/unit/policies/base.py index 68a051b26c4e..7490441d9260 100644 --- a/nova/tests/unit/policies/base.py +++ b/nova/tests/unit/policies/base.py @@ -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()) diff --git a/nova/tests/unit/test_policy.py b/nova/tests/unit/test_policy.py index 871e836d877b..752b8723810b 100644 --- a/nova/tests/unit/test_policy.py +++ b/nova/tests/unit/test_policy.py @@ -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", diff --git a/releasenotes/notes/enable-enforce-scope-and-new-defaults-14db8c75b263b599.yaml b/releasenotes/notes/enable-enforce-scope-and-new-defaults-14db8c75b263b599.yaml new file mode 100644 index 000000000000..72a6f861b6fa --- /dev/null +++ b/releasenotes/notes/enable-enforce-scope-and-new-defaults-14db8c75b263b599.yaml @@ -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 diff --git a/requirements.txt b/requirements.txt index dc1c414aba44..5301b7cf0579 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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