[S-RBAC] Allow admin user to do all API requests by default

By default ADMIN user in the new Secure RBAC policies should behave in
the same way as in the legacy rules so basically every API operation for
any project should be allowed for ADMIN user.
In the new rules there are roles like PROJECT_MEMBER and PROJECT_READER
and those personas don't inherits directly from ADMIN which means that
if something is possible to e.g. PROJECT_MEMBER it isn't automatically
also allowed to ADMIN and we need to explicitly allow ADMIN user to do
such requests. It was done like that for many of API calls already but
not for all of them (probably by mistake).

This patch introduces new composite check ADMIN_OR_PROJECT_MEMBER and
uses it in the check strings where ADMIN or PROJECT_MEMBER user is
allowed to use the API.
It also changes some of the check strings which used "policy_or" to
combine ADMIN and PROJECT_MEMBER or PROJECT_READER so that those
composite checks ADMIN_OR_PROJECT_MEMBER and ADMIN_OR_PROJECT_READER are
used everywhere.

Closes-Bug: #1997089

Change-Id: Iab5cd6c7aa07ca8527c5fa8396c9ed0da65b4fa7
This commit is contained in:
Slawek Kaplonski 2022-11-21 15:32:21 +01:00
parent a76b20dbc7
commit 6d8ada0ac9
31 changed files with 441 additions and 279 deletions

View File

@ -32,7 +32,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_address_group',
check_str=base.policy_or(
base.PROJECT_READER,
base.ADMIN_OR_PROJECT_READER,
'rule:shared_address_groups'),
description='Get an address group',
operations=[

View File

@ -31,9 +31,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='create_address_scope',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Create an address scope',
operations=[
{
@ -92,9 +90,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_address_scope',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Update an address scope',
operations=[
{
@ -128,9 +124,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_address_scope',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Delete an address scope',
operations=[
{

View File

@ -25,7 +25,7 @@ DEPRECATION_REASON = (
rules = [
policy.DocumentedRuleDefault(
name='get_auto_allocated_topology',
check_str=base.PROJECT_READER,
check_str=base.ADMIN_OR_PROJECT_READER,
description="Get a project's auto-allocated topology",
operations=[
{
@ -42,7 +42,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_auto_allocated_topology',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description="Delete a project's auto-allocated topology",
operations=[
{

View File

@ -49,9 +49,11 @@ PROJECT_MEMBER = 'role:member and project_id:%(project_id)s'
PROJECT_READER = 'role:reader and project_id:%(project_id)s'
# The following are common composite check strings that are useful for
# protecting APIs designed to operate with multiple scopes (e.g., a system
# administrator should be able to delete any router in the deployment, a
# protecting APIs designed to operate with multiple scopes (e.g.,
# an administrator should be able to delete any router in the deployment, a
# project member should only be able to delete routers in their project).
ADMIN_OR_PROJECT_MEMBER = (
'(' + ADMIN + ') or (' + PROJECT_MEMBER + ')')
ADMIN_OR_PROJECT_READER = (
'(' + ADMIN + ') or (' + PROJECT_READER + ')')

View File

@ -25,9 +25,7 @@ DEPRECATION_REASON = (
rules = [
policy.DocumentedRuleDefault(
name='create_floatingip',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Create a floating IP',
operations=[
{
@ -61,9 +59,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_floatingip',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
description='Get a floating IP',
operations=[
{
@ -84,9 +80,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_floatingip',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Update a floating IP',
operations=[
{
@ -103,9 +97,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_floatingip',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Delete a floating IP',
operations=[
{

View File

@ -21,7 +21,7 @@ DEPRECATED_REASON = (
rules = [
policy.DocumentedRuleDefault(
name='get_floatingip_pool',
check_str=base.PROJECT_READER,
check_str=base.ADMIN_OR_PROJECT_READER,
description='Get floating IP pools',
operations=[
{

View File

@ -30,7 +30,7 @@ rules = [
policy.DocumentedRuleDefault(
name='create_floatingip_port_forwarding',
check_str=base.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Create a floating IP port forwarding',
@ -49,7 +49,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_floatingip_port_forwarding',
check_str=base.policy_or(
base.PROJECT_READER,
base.ADMIN_OR_PROJECT_READER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Get a floating IP port forwarding',
@ -72,7 +72,7 @@ rules = [
policy.DocumentedRuleDefault(
name='update_floatingip_port_forwarding',
check_str=base.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Update a floating IP port forwarding',
@ -91,7 +91,7 @@ rules = [
policy.DocumentedRuleDefault(
name='delete_floatingip_port_forwarding',
check_str=base.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Delete a floating IP port forwarding',

View File

@ -30,7 +30,7 @@ rules = [
policy.DocumentedRuleDefault(
name='create_router_conntrack_helper',
check_str=base.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Create a router conntrack helper',
@ -49,7 +49,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_router_conntrack_helper',
check_str=base.policy_or(
base.PROJECT_READER,
base.ADMIN_OR_PROJECT_READER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Get a router conntrack helper',
@ -72,7 +72,7 @@ rules = [
policy.DocumentedRuleDefault(
name='update_router_conntrack_helper',
check_str=base.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Update a router conntrack helper',
@ -91,7 +91,7 @@ rules = [
policy.DocumentedRuleDefault(
name='delete_router_conntrack_helper',
check_str=base.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Delete a router conntrack helper',

View File

@ -25,7 +25,7 @@ DEPRECATION_REASON = (
rules = [
policy.DocumentedRuleDefault(
name='create_local_ip',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Create a Local IP',
operations=[
{
@ -42,7 +42,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_local_ip',
check_str=base.PROJECT_READER,
check_str=base.ADMIN_OR_PROJECT_READER,
description='Get a Local IP',
operations=[
{
@ -63,7 +63,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_local_ip',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Update a Local IP',
operations=[
{
@ -80,7 +80,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_local_ip',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Delete a Local IP',
operations=[
{

View File

@ -27,7 +27,7 @@ rules = [
policy.DocumentedRuleDefault(
name='create_local_ip_port_association',
check_str=base.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Create a Local IP port association',
@ -46,7 +46,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_local_ip_port_association',
check_str=base.policy_or(
base.PROJECT_READER,
base.ADMIN_OR_PROJECT_READER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Get a Local IP port association',
@ -69,7 +69,7 @@ rules = [
policy.DocumentedRuleDefault(
name='delete_local_ip_port_association',
check_str=base.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_PARENT_OWNER),
scope_types=['project'],
description='Delete a Local IP port association',

View File

@ -46,9 +46,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_metering_label',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a metering label',
operations=[
@ -103,9 +101,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_metering_label_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a metering label rule',
operations=[

View File

@ -25,7 +25,7 @@ DEPRECATION_REASON = (
rules = [
policy.DocumentedRuleDefault(
name='create_ndp_proxy',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Create a ndp proxy',
operations=[
{
@ -42,7 +42,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_ndp_proxy',
check_str=base.PROJECT_READER,
check_str=base.ADMIN_OR_PROJECT_READER,
description='Get a ndp proxy',
operations=[
{
@ -63,7 +63,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_ndp_proxy',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Update a ndp proxy',
operations=[
{
@ -80,7 +80,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_ndp_proxy',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
description='Delete a ndp proxy',
operations=[
{

View File

@ -45,9 +45,7 @@ rules = [
policy.DocumentedRuleDefault(
name='create_network',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Create a network',
operations=ACTION_POST,
@ -95,9 +93,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='create_network:port_security_enabled',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description=(
'Specify ``port_security_enabled`` '
@ -170,8 +166,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_network',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER,
base.ADMIN_OR_PROJECT_READER,
'rule:shared',
'rule:external',
base.RULE_ADVSVC
@ -240,9 +235,7 @@ rules = [
policy.DocumentedRuleDefault(
name='update_network',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Update a network',
operations=ACTION_PUT,
@ -344,9 +337,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_network:port_security_enabled',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Update ``port_security_enabled`` attribute of a network',
operations=ACTION_PUT,
@ -359,9 +350,7 @@ rules = [
policy.DocumentedRuleDefault(
name='delete_network',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Delete a network',
operations=ACTION_DELETE,

View File

@ -51,9 +51,7 @@ rules = [
policy.DocumentedRuleDefault(
name='create_port',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Create a port',
operations=ACTION_POST,
@ -207,9 +205,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='create_port:binding:vnic_type',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description=(
'Specify ``binding:vnic_type`` '

View File

@ -23,9 +23,7 @@ The QoS API now supports project scope and default roles.
rules = [
policy.DocumentedRuleDefault(
name='get_policy',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get QoS policies',
operations=[
@ -120,9 +118,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_policy_bandwidth_limit_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a QoS bandwidth limit rule',
operations=[
@ -198,9 +194,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_policy_packet_rate_limit_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a QoS packet rate limit rule',
operations=[
@ -256,9 +250,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_policy_dscp_marking_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a QoS DSCP marking rule',
operations=[
@ -334,9 +326,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_policy_minimum_bandwidth_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a QoS minimum bandwidth rule',
operations=[
@ -411,9 +401,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_policy_minimum_packet_rate_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a QoS minimum packet rate rule',
operations=[
@ -468,9 +456,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_alias_bandwidth_limit_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a QoS bandwidth limit rule through alias',
operations=[
@ -521,9 +507,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_alias_dscp_marking_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a QoS DSCP marking rule through alias',
operations=[
@ -574,9 +558,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_alias_minimum_bandwidth_rule',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a QoS minimum bandwidth rule through alias',
operations=[

View File

@ -36,9 +36,7 @@ rules = [
policy.DocumentedRuleDefault(
name='create_rbac_policy',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Create an RBAC policy',
operations=[
@ -77,9 +75,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_rbac_policy',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Update an RBAC policy',
operations=[
@ -120,9 +116,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_rbac_policy',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get an RBAC policy',
operations=[
@ -143,9 +137,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_rbac_policy',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Delete an RBAC policy',
operations=[

View File

@ -39,9 +39,7 @@ ACTION_GET = [
rules = [
policy.DocumentedRuleDefault(
name='create_router',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Create a router',
operations=ACTION_POST,
@ -77,9 +75,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='create_router:external_gateway_info',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description=('Specify ``external_gateway_info`` '
'information when creating a router'),
@ -92,9 +88,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='create_router:external_gateway_info:network_id',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description=('Specify ``network_id`` in ``external_gateway_info`` '
'information when creating a router'),
@ -135,9 +129,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_router',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER),
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a router',
operations=ACTION_GET,
@ -174,9 +166,7 @@ rules = [
policy.DocumentedRuleDefault(
name='update_router',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Update a router',
operations=ACTION_PUT,
@ -212,9 +202,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_router:external_gateway_info',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Update ``external_gateway_info`` information of a router',
operations=ACTION_PUT,
@ -226,9 +214,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_router:external_gateway_info:network_id',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description=('Update ``network_id`` attribute of '
'``external_gateway_info`` information of a router'),
@ -268,9 +254,7 @@ rules = [
policy.DocumentedRuleDefault(
name='delete_router',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Delete a router',
operations=ACTION_DELETE,
@ -283,9 +267,7 @@ rules = [
policy.DocumentedRuleDefault(
name='add_router_interface',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Add an interface to a router',
operations=[
@ -302,9 +284,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='remove_router_interface',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Remove an interface from a router',
operations=[
@ -321,9 +301,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='add_extraroutes',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Add extra route to a router',
operations=[
@ -340,9 +318,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='remove_extraroutes',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Remove extra route from a router',
operations=[

View File

@ -46,7 +46,7 @@ rules = [
# Does an empty string make more sense for create_security_group?
policy.DocumentedRuleDefault(
name='create_security_group',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Create a security group',
operations=[
@ -63,7 +63,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_security_group',
check_str=base.PROJECT_READER,
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a security group',
operations=[
@ -84,7 +84,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_security_group',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Update a security group',
operations=[
@ -101,7 +101,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_security_group',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Delete a security group',
operations=[
@ -121,7 +121,7 @@ rules = [
# Does an empty string make more sense for create_security_group_rule?
policy.DocumentedRuleDefault(
name='create_security_group_rule',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Create a security group rule',
operations=[
@ -139,7 +139,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_security_group_rule',
check_str=base.policy_or(
base.PROJECT_READER,
base.ADMIN_OR_PROJECT_READER,
base.RULE_SG_OWNER),
scope_types=['project'],
description='Get a security group rule',
@ -161,7 +161,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_security_group_rule',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Delete a security group rule',
operations=[

View File

@ -40,8 +40,7 @@ rules = [
policy.DocumentedRuleDefault(
name='create_subnet',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_NET_OWNER),
scope_types=['project'],
description='Create a subnet',
@ -83,8 +82,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_subnet',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER,
base.ADMIN_OR_PROJECT_READER,
'rule:shared'),
scope_types=['project'],
description='Get a subnet',
@ -112,8 +110,7 @@ rules = [
policy.DocumentedRuleDefault(
name='update_subnet',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_NET_OWNER),
scope_types=['project'],
description='Update a subnet',
@ -151,8 +148,7 @@ rules = [
policy.DocumentedRuleDefault(
name='delete_subnet',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER,
base.ADMIN_OR_PROJECT_MEMBER,
base.RULE_NET_OWNER),
scope_types=['project'],
description='Delete a subnet',

View File

@ -33,9 +33,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='create_subnetpool',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Create a subnetpool',
operations=[
@ -89,8 +87,7 @@ rules = [
policy.DocumentedRuleDefault(
name='get_subnetpool',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_READER,
base.ADMIN_OR_PROJECT_READER,
'rule:shared_subnetpools'
),
scope_types=['project'],
@ -115,9 +112,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_subnetpool',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Update a subnetpool',
operations=[
@ -151,9 +146,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_subnetpool',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Delete a subnetpool',
operations=[
@ -170,9 +163,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='onboard_network_subnets',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Onboard existing subnet into a subnetpool',
operations=[
@ -189,9 +180,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='add_prefixes',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Add prefixes to a subnetpool',
operations=[
@ -208,9 +197,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='remove_prefixes',
check_str=base.policy_or(
base.ADMIN,
base.PROJECT_MEMBER),
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Remove unallocated prefixes from a subnetpool',
operations=[

View File

@ -26,7 +26,7 @@ DEPRECATED_REASON = (
rules = [
policy.DocumentedRuleDefault(
name='create_trunk',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Create a trunk',
operations=[
@ -43,7 +43,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_trunk',
check_str=base.PROJECT_READER,
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='Get a trunk',
operations=[
@ -64,7 +64,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='update_trunk',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Update a trunk',
operations=[
@ -81,7 +81,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='delete_trunk',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Delete a trunk',
operations=[
@ -98,7 +98,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='get_subports',
check_str=base.PROJECT_READER,
check_str=base.ADMIN_OR_PROJECT_READER,
scope_types=['project'],
description='List subports attached to a trunk',
operations=[
@ -115,7 +115,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='add_subports',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Add subports to a trunk',
operations=[
@ -132,7 +132,7 @@ rules = [
),
policy.DocumentedRuleDefault(
name='remove_subports',
check_str=base.PROJECT_MEMBER,
check_str=base.ADMIN_OR_PROJECT_MEMBER,
scope_types=['project'],
description='Delete subports from a trunk',
operations=[

View File

@ -67,10 +67,8 @@ class AdminTests(AddressGroupAPITestCase):
def test_get_address_group(self):
self.assertTrue(
policy.enforce(self.context, "get_address_group", self.target))
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce,
self.context, "get_address_group", self.alt_target)
self.assertTrue(
policy.enforce(self.context, "get_address_group", self.alt_target))
class ProjectMemberTests(AdminTests):
@ -79,6 +77,14 @@ class ProjectMemberTests(AdminTests):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_get_address_group(self):
self.assertTrue(
policy.enforce(self.context, "get_address_group", self.target))
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce,
self.context, "get_address_group", self.alt_target)
class ProjectReaderTests(ProjectMemberTests):

View File

@ -94,6 +94,25 @@ class AdminTests(AutoAllocatedTopologyAPITestCase):
super(AdminTests, self).setUp()
self.context = self.project_admin_ctx
def test_get_topology(self):
self.assertTrue(
policy.enforce(self.context, GET_POLICY, self.target))
self.assertTrue(
policy.enforce(self.context, GET_POLICY, self.alt_target))
def test_delete_topology(self):
self.assertTrue(
policy.enforce(self.context, DELETE_POLICY, self.target))
self.assertTrue(
policy.enforce(self.context, DELETE_POLICY, self.alt_target))
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_get_topology(self):
self.assertTrue(policy.enforce(self.context, GET_POLICY, self.target))
self.assertRaises(
@ -115,13 +134,6 @@ class AdminTests(AutoAllocatedTopologyAPITestCase):
)
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
class ProjectReaderTests(ProjectMemberTests):
def setUp(self):

View File

@ -64,12 +64,9 @@ class AdminTests(FloatingipPoolsAPITestCase):
self.assertTrue(
policy.enforce(self.context, 'get_floatingip_pool',
self.target))
def test_get_floatingip_pool_other_project(self):
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce,
self.context, 'get_floatingip_pool', self.alt_target)
self.assertTrue(
policy.enforce(self.context, 'get_floatingip_pool',
self.alt_target))
class ProjectMemberTests(AdminTests):
@ -78,8 +75,17 @@ class ProjectMemberTests(AdminTests):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_get_floatingip_pool(self):
self.assertTrue(
policy.enforce(self.context, 'get_floatingip_pool',
self.target))
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce,
self.context, 'get_floatingip_pool', self.alt_target)
class ProjectReaderTests(AdminTests):
class ProjectReaderTests(ProjectMemberTests):
def setUp(self):
super(ProjectReaderTests, self).setUp()

View File

@ -121,6 +121,53 @@ class AdminTests(FloatingipPortForwardingAPITestCase):
super(AdminTests, self).setUp()
self.context = self.project_admin_ctx
def test_create_fip_pf(self):
self.assertTrue(
policy.enforce(self.context,
'create_floatingip_port_forwarding',
self.target))
self.assertTrue(
policy.enforce(self.context,
'create_floatingip_port_forwarding',
self.alt_target))
def test_get_fip_pf(self):
self.assertTrue(
policy.enforce(self.context,
'get_floatingip_port_forwarding',
self.target))
self.assertTrue(
policy.enforce(self.context,
'get_floatingip_port_forwarding',
self.alt_target))
def test_update_fip_pf(self):
self.assertTrue(
policy.enforce(self.context,
'update_floatingip_port_forwarding',
self.target))
self.assertTrue(
policy.enforce(self.context,
'update_floatingip_port_forwarding',
self.alt_target))
def test_delete_fip_pf(self):
self.assertTrue(
policy.enforce(self.context,
'delete_floatingip_port_forwarding',
self.target))
self.assertTrue(
policy.enforce(self.context,
'delete_floatingip_port_forwarding',
self.alt_target))
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_create_fip_pf(self):
self.assertTrue(
policy.enforce(self.context,
@ -166,13 +213,6 @@ class AdminTests(FloatingipPortForwardingAPITestCase):
self.alt_target)
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
class ProjectReaderTests(ProjectMemberTests):
def setUp(self):

View File

@ -113,6 +113,45 @@ class AdminTests(L3ConntrackHelperAPITestCase):
super(AdminTests, self).setUp()
self.context = self.project_admin_ctx
def test_create_router_conntrack_helper(self):
self.assertTrue(
policy.enforce(self.context,
'create_router_conntrack_helper', self.target))
self.assertTrue(
policy.enforce(self.context,
'create_router_conntrack_helper', self.alt_target))
def test_get_router_conntrack_helper(self):
self.assertTrue(
policy.enforce(self.context,
'get_router_conntrack_helper', self.target))
self.assertTrue(
policy.enforce(self.context,
'get_router_conntrack_helper', self.alt_target))
def test_update_router_conntrack_helper(self):
self.assertTrue(
policy.enforce(self.context,
'update_router_conntrack_helper', self.target))
self.assertTrue(
policy.enforce(self.context,
'update_router_conntrack_helper', self.alt_target))
def test_delete_router_conntrack_helper(self):
self.assertTrue(
policy.enforce(self.context,
'delete_router_conntrack_helper', self.target))
self.assertTrue(
policy.enforce(self.context,
'delete_router_conntrack_helper', self.alt_target))
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_create_router_conntrack_helper(self):
self.assertTrue(
policy.enforce(self.context,
@ -150,13 +189,6 @@ class AdminTests(L3ConntrackHelperAPITestCase):
self.context, 'delete_router_conntrack_helper', self.alt_target)
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
class ProjectReaderTests(ProjectMemberTests):
def setUp(self):

View File

@ -81,38 +81,26 @@ class AdminTests(LocalIPAPITestCase):
def test_create_local_ip(self):
self.assertTrue(
policy.enforce(self.context, "create_local_ip", self.target))
def test_create_local_ip_other_project(self):
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce, self.context, "create_local_ip", self.alt_target)
self.assertTrue(
policy.enforce(self.context, "create_local_ip", self.alt_target))
def test_get_local_ip(self):
self.assertTrue(
policy.enforce(self.context, "get_local_ip", self.target))
def test_get_local_ip_other_project(self):
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce, self.context, "get_local_ip", self.alt_target)
self.assertTrue(
policy.enforce(self.context, "get_local_ip", self.alt_target))
def test_update_local_ip(self):
self.assertTrue(
policy.enforce(self.context, "update_local_ip", self.target))
def test_update_local_ip_other_project(self):
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce, self.context, "update_local_ip", self.alt_target)
self.assertTrue(
policy.enforce(self.context, "update_local_ip", self.alt_target))
def test_delete_local_ip(self):
self.assertTrue(
policy.enforce(self.context, "delete_local_ip", self.target))
def test_delete_local_ip_other_project(self):
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce, self.context, "delete_local_ip", self.alt_target)
self.assertTrue(
policy.enforce(self.context, "delete_local_ip", self.alt_target))
class ProjectMemberTests(AdminTests):
@ -121,6 +109,34 @@ class ProjectMemberTests(AdminTests):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_create_local_ip(self):
self.assertTrue(
policy.enforce(self.context, "create_local_ip", self.target))
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce, self.context, "create_local_ip", self.alt_target)
def test_get_local_ip(self):
self.assertTrue(
policy.enforce(self.context, "get_local_ip", self.target))
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce, self.context, "get_local_ip", self.alt_target)
def test_update_local_ip(self):
self.assertTrue(
policy.enforce(self.context, "update_local_ip", self.target))
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce, self.context, "update_local_ip", self.alt_target)
def test_delete_local_ip(self):
self.assertTrue(
policy.enforce(self.context, "delete_local_ip", self.target))
self.assertRaises(
base_policy.PolicyNotAuthorized,
policy.enforce, self.context, "delete_local_ip", self.alt_target)
class ProjectReaderTests(LocalIPAPITestCase):

View File

@ -109,6 +109,43 @@ class AdminTests(LocalIPAssociationAPITestCase):
super(AdminTests, self).setUp()
self.context = self.project_admin_ctx
def test_create_local_ip_port_association(self):
self.assertTrue(
policy.enforce(self.context,
'create_local_ip_port_association',
self.target))
self.assertTrue(
policy.enforce(self.context,
'create_local_ip_port_association',
self.alt_target))
def test_get_local_ip_port_association(self):
self.assertTrue(
policy.enforce(self.context,
'get_local_ip_port_association',
self.target))
self.assertTrue(
policy.enforce(self.context,
'get_local_ip_port_association',
self.alt_target))
def test_delete_local_ip_port_association(self):
self.assertTrue(
policy.enforce(self.context,
'delete_local_ip_port_association',
self.target))
self.assertTrue(
policy.enforce(self.context,
'delete_local_ip_port_association',
self.alt_target))
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_create_local_ip_port_association(self):
self.assertTrue(
policy.enforce(self.context,
@ -143,13 +180,6 @@ class AdminTests(LocalIPAssociationAPITestCase):
self.alt_target)
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
class ProjectReaderTests(ProjectMemberTests):
def setUp(self):

View File

@ -94,6 +94,37 @@ class AdminTests(NDPProxyAPITestCase):
super(AdminTests, self).setUp()
self.context = self.project_admin_ctx
def test_create_ndp_proxy(self):
self.assertTrue(
policy.enforce(self.context, "create_ndp_proxy", self.target))
self.assertTrue(
policy.enforce(self.context, "create_ndp_proxy", self.alt_target))
def test_get_ndp_proxy(self):
self.assertTrue(
policy.enforce(self.context, "get_ndp_proxy", self.target))
self.assertTrue(
policy.enforce(self.context, "get_ndp_proxy", self.alt_target))
def test_update_ndp_proxy(self):
self.assertTrue(
policy.enforce(self.context, "update_ndp_proxy", self.target))
self.assertTrue(
policy.enforce(self.context, "update_ndp_proxy", self.alt_target))
def test_delete_ndp_proxy(self):
self.assertTrue(
policy.enforce(self.context, "delete_ndp_proxy", self.target))
self.assertTrue(
policy.enforce(self.context, "delete_ndp_proxy", self.alt_target))
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_create_ndp_proxy(self):
self.assertTrue(
policy.enforce(self.context, "create_ndp_proxy", self.target))
@ -124,13 +155,6 @@ class AdminTests(NDPProxyAPITestCase):
policy.enforce, self.context, "delete_ndp_proxy", self.alt_target)
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
class ProjectReaderTests(ProjectMemberTests):
def setUp(self):

View File

@ -97,6 +97,41 @@ class AdminSecurityGroupTests(SecurityGroupAPITestCase):
super(AdminSecurityGroupTests, self).setUp()
self.context = self.project_admin_ctx
def test_create_security_group(self):
self.assertTrue(
policy.enforce(self.context, 'create_security_group', self.target))
self.assertTrue(
policy.enforce(
self.context, 'create_security_group', self.alt_target))
def test_get_security_group(self):
self.assertTrue(
policy.enforce(self.context, 'get_security_group', self.target))
self.assertTrue(
policy.enforce(
self.context, 'get_security_group', self.alt_target))
def test_update_security_group(self):
self.assertTrue(
policy.enforce(self.context, 'update_security_group', self.target))
self.assertTrue(
policy.enforce(
self.context, 'update_security_group', self.alt_target))
def test_delete_security_group(self):
self.assertTrue(
policy.enforce(self.context, 'delete_security_group', self.target))
self.assertTrue(
policy.enforce(
self.context, 'delete_security_group', self.alt_target))
class ProjectMemberSecurityGroupTests(AdminSecurityGroupTests):
def setUp(self):
super(ProjectMemberSecurityGroupTests, self).setUp()
self.context = self.project_member_ctx
def test_create_security_group(self):
self.assertTrue(
policy.enforce(self.context, 'create_security_group', self.target))
@ -130,13 +165,6 @@ class AdminSecurityGroupTests(SecurityGroupAPITestCase):
self.context, 'delete_security_group', self.alt_target)
class ProjectMemberSecurityGroupTests(AdminSecurityGroupTests):
def setUp(self):
super(ProjectMemberSecurityGroupTests, self).setUp()
self.context = self.project_member_ctx
class ProjectReaderSecurityGroupTests(ProjectMemberSecurityGroupTests):
def setUp(self):
@ -255,6 +283,37 @@ class AdminSecurityGroupRuleTests(SecurityGroupRuleAPITestCase):
super(AdminSecurityGroupRuleTests, self).setUp()
self.context = self.project_admin_ctx
def test_create_security_group_rule(self):
self.assertTrue(
policy.enforce(self.context,
'create_security_group_rule', self.target))
self.assertTrue(
policy.enforce(self.context,
'create_security_group_rule', self.alt_target))
def test_get_security_group_rule(self):
self.assertTrue(
policy.enforce(self.context,
'get_security_group_rule', self.target))
self.assertTrue(
policy.enforce(self.context,
'get_security_group_rule', self.alt_target))
def test_delete_security_group_rule(self):
self.assertTrue(
policy.enforce(self.context,
'delete_security_group_rule', self.target))
self.assertTrue(
policy.enforce(self.context,
'delete_security_group_rule', self.alt_target))
class ProjectMemberSecurityGroupRuleTests(AdminSecurityGroupRuleTests):
def setUp(self):
super(ProjectMemberSecurityGroupRuleTests, self).setUp()
self.context = self.project_member_ctx
def test_create_security_group_rule(self):
self.assertTrue(
policy.enforce(self.context,
@ -294,13 +353,6 @@ class AdminSecurityGroupRuleTests(SecurityGroupRuleAPITestCase):
self.context, 'delete_security_group_rule', self.alt_target)
class ProjectMemberSecurityGroupRuleTests(AdminSecurityGroupRuleTests):
def setUp(self):
super(ProjectMemberSecurityGroupRuleTests, self).setUp()
self.context = self.project_member_ctx
class ProjectReaderSecurityGroupRuleTests(ProjectMemberSecurityGroupRuleTests):
def setUp(self):

View File

@ -124,6 +124,55 @@ class AdminTests(TrunkAPITestCase):
super(AdminTests, self).setUp()
self.context = self.project_admin_ctx
def test_create_trunk(self):
self.assertTrue(
policy.enforce(self.context, 'create_trunk', self.target))
self.assertTrue(
policy.enforce(self.context, 'create_trunk', self.alt_target))
def test_get_trunk(self):
self.assertTrue(
policy.enforce(self.context, 'get_trunk', self.target))
self.assertTrue(
policy.enforce(self.context, 'get_trunk', self.alt_target))
def test_update_trunk(self):
self.assertTrue(
policy.enforce(self.context, 'update_trunk', self.target))
self.assertTrue(
policy.enforce(self.context, 'update_trunk', self.alt_target))
def test_delete_trunk(self):
self.assertTrue(
policy.enforce(self.context, 'delete_trunk', self.target))
self.assertTrue(
policy.enforce(self.context, 'delete_trunk', self.alt_target))
def test_get_subports(self):
self.assertTrue(
policy.enforce(self.context, 'get_subports', self.target))
self.assertTrue(
policy.enforce(self.context, 'get_subports', self.alt_target))
def test_add_subports(self):
self.assertTrue(
policy.enforce(self.context, 'add_subports', self.target))
self.assertTrue(
policy.enforce(self.context, 'add_subports', self.alt_target))
def test_remove_subports(self):
self.assertTrue(
policy.enforce(self.context, 'remove_subports', self.target))
self.assertTrue(
policy.enforce(self.context, 'remove_subports', self.alt_target))
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
def test_create_trunk(self):
self.assertTrue(
policy.enforce(self.context, 'create_trunk', self.target))
@ -181,13 +230,6 @@ class AdminTests(TrunkAPITestCase):
self.context, 'remove_subports', self.alt_target)
class ProjectMemberTests(AdminTests):
def setUp(self):
super(ProjectMemberTests, self).setUp()
self.context = self.project_member_ctx
class ProjectReaderTests(ProjectMemberTests):
def setUp(self):