Add new default roles in tenant tenant usage policies

This adds new defaults roles in tenant tenant usage API policies.
This policy is default to:
- PROJECT_MEMBER_OR_SYSTEM_ADMIN for tenant usage statistics for
a specific tenant
- SYSTEM_ADMIN for list tenant usage statistics.

Also add tests to simulates the future where we drop the deprecation
fall back in the policy by overriding the rules with a version where
there are no deprecated rule options. Operators can do the same by
adding overrides in their policy files that match the default but
stop the rule deprecation fallback from happening.

Partial implement blueprint policy-defaults-refresh

Change-Id: I6756859fd68e71f829dfcf5bf7bcb8b7c2cdb75a
This commit is contained in:
Ghanshyam Mann 2020-04-05 04:36:28 -05:00
parent 86655fe07f
commit 2a11f9598f
3 changed files with 59 additions and 30 deletions

View File

@ -24,7 +24,7 @@ POLICY_ROOT = 'os_compute_api:os-simple-tenant-usage:%s'
simple_tenant_usage_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.RULE_ADMIN_OR_OWNER,
check_str=base.PROJECT_READER_OR_SYSTEM_READER,
description="Show usage statistics for a specific tenant",
operations=[
{
@ -35,7 +35,7 @@ simple_tenant_usage_policies = [
scope_types=['system', 'project']),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'list',
check_str=base.RULE_ADMIN_API,
check_str=base.SYSTEM_READER,
description="List per tenant usage statistics for all tenants",
operations=[
{

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
from nova.api.openstack.compute import simple_tenant_usage
from nova.policies import simple_tenant_usage as policies
from nova.tests.unit.api.openstack import fakes
@ -28,45 +30,46 @@ class SimpleTenantUsagePolicyTest(base.BasePolicyTest):
super(SimpleTenantUsagePolicyTest, self).setUp()
self.controller = simple_tenant_usage.SimpleTenantUsageController()
self.req = fakes.HTTPRequest.blank('')
self.controller._get_instances_all_cells = mock.MagicMock()
# Check that admin or and owner is able to get
# Check that reader(legacy admin) or and owner is able to get
# the tenant usage statistics for a specific tenant.
self.admin_or_owner_authorized_contexts = [
self.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.project_foo_context]
# Check that non-admin/owner is not able to get
self.project_reader_context, self.project_foo_context,
self.system_member_context, self.system_reader_context]
# Check that non-reader(legacy non-admin) or owner is not able to get
# the tenant usage statistics for a specific tenant.
self.admin_or_owner_unauthorized_contexts = [
self.system_member_context, self.system_reader_context,
self.reader_or_owner_unauthorized_contexts = [
self.system_foo_context, self.other_project_member_context,
self.other_project_reader_context,
self.other_project_reader_context
]
# Check that admin is able to get the tenant usage statistics.
self.admin_authorized_contexts = [
# Check that reader is able to get the tenant usage statistics.
self.reader_authorized_contexts = [
self.legacy_admin_context, self.system_admin_context,
self.project_admin_context]
# Check that non-admin is not able to get the tenant usage statistics.
self.admin_unauthorized_contexts = [
self.system_member_context, self.system_reader_context,
self.project_admin_context, self.system_member_context,
self.system_reader_context]
# Check that non-reader is not able to get the tenant usage statistics.
self.reader_unauthorized_contexts = [
self.system_foo_context, self.project_member_context,
self.other_project_member_context,
self.project_foo_context, self.project_reader_context,
self.other_project_reader_context,
self.other_project_reader_context
]
def test_index_simple_tenant_usage_policy(self):
rule_name = policies.POLICY_ROOT % 'list'
self.common_policy_check(self.admin_authorized_contexts,
self.admin_unauthorized_contexts,
self.common_policy_check(self.reader_authorized_contexts,
self.reader_unauthorized_contexts,
rule_name,
self.controller.index,
self.req)
def test_show_simple_tenant_usage_policy(self):
rule_name = policies.POLICY_ROOT % 'show'
self.common_policy_check(self.admin_or_owner_authorized_contexts,
self.admin_or_owner_unauthorized_contexts,
self.common_policy_check(self.reader_or_owner_authorized_contexts,
self.reader_or_owner_unauthorized_contexts,
rule_name,
self.controller.show,
self.req, self.project_id)
@ -86,15 +89,41 @@ class SimpleTenantUsageScopeTypePolicyTest(SimpleTenantUsagePolicyTest):
super(SimpleTenantUsageScopeTypePolicyTest, self).setUp()
self.flags(enforce_scope=True, group="oslo_policy")
# Check that system admin is able to get the tenant usage statistics.
self.admin_authorized_contexts = [
self.system_admin_context]
# Check that non-system/admin is not able to get the tenant usage
# Check that system reader is able to get the tenant usage statistics.
self.reader_authorized_contexts = [
self.system_admin_context, self.system_member_context,
self.system_reader_context]
# Check that non-system/reader is not able to get the tenant usage
# statistics.
self.admin_unauthorized_contexts = [
self.legacy_admin_context, self.system_member_context,
self.system_reader_context, self.system_foo_context,
self.reader_unauthorized_contexts = [
self.legacy_admin_context, self.system_foo_context,
self.project_admin_context, self.project_member_context,
self.other_project_member_context,
self.project_foo_context, self.project_reader_context
self.project_foo_context, self.project_reader_context,
self.other_project_reader_context
]
class SimpleTenantUsageNoLegacyPolicyTest(
SimpleTenantUsageScopeTypePolicyTest):
"""Test Simple Tenant Usage APIs policies with system scope enabled,
and no more deprecated rules that allow the legacy admin API to
access system APIs.
"""
without_deprecated_rules = True
def setUp(self):
super(SimpleTenantUsageNoLegacyPolicyTest, self).setUp()
# Check that system reader or owner is able to get
# the tenant usage statistics for a specific tenant.
self.reader_or_owner_authorized_contexts = [
self.system_admin_context, self.system_member_context,
self.system_reader_context, self.project_admin_context,
self.project_member_context, self.project_reader_context]
# Check that non-system reader/owner is not able to get
# the tenant usage statistics for a specific tenant.
self.reader_or_owner_unauthorized_contexts = [
self.legacy_admin_context, self.system_foo_context,
self.other_project_member_context,
self.project_foo_context, self.other_project_reader_context
]

View File

@ -353,7 +353,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
"os_compute_api:os-services:update",
"os_compute_api:os-services:delete",
"os_compute_api:os-shelve:shelve_offload",
"os_compute_api:os-simple-tenant-usage:list",
"os_compute_api:os-availability-zone:detail",
"os_compute_api:os-assisted-volume-snapshots:create",
"os_compute_api:os-assisted-volume-snapshots:delete",
@ -388,7 +387,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
"os_compute_api:server-metadata:create",
"os_compute_api:server-metadata:update",
"os_compute_api:server-metadata:update_all",
"os_compute_api:os-simple-tenant-usage:show",
"os_compute_api:os-suspend-server:suspend",
"os_compute_api:os-suspend-server:resume",
"os_compute_api:os-tenant-networks",
@ -455,6 +453,7 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
self.system_reader_rules = (
"os_compute_api:servers:migrations:index",
"os_compute_api:servers:migrations:show",
"os_compute_api:os-simple-tenant-usage:list",
"os_compute_api:os-migrations:index",
"os_compute_api:os-services:list",
"os_compute_api:os-instance-actions:events:details",
@ -472,6 +471,7 @@ class RealRolePolicyTestCase(test.NoDBTestCase):
)
self.system_reader_or_owner_rules = (
"os_compute_api:os-simple-tenant-usage:show",
"os_compute_api:os-security-groups:list",
"os_compute_api:os-volumes-attachments:index",
"os_compute_api:os-volumes-attachments:show",