From 0741a0d5a55024787c7324d060bd3f5a79ffcb0e Mon Sep 17 00:00:00 2001 From: Slawek Kaplonski Date: Fri, 21 Jul 2023 10:11:47 +0200 Subject: [PATCH] Add NET_OWNER_MEMBER and NET_OWNER_READER policy rules Initially when [1] was proposed the idea was to use PARENT_OWNER_* rules for the subnet APIs, in the same way as it is done currently for e.g. FIP PF, QoS rules and some other resources. But after some more thinking about it, it's better to keep NET_OWNER rules for MEMBER and READER. Those rules are basically very similar to the PARENT_OWNER_*, the only difference is that it relies on the "network_id" attribute always. The reason why it's better to have NET_OWNER_* rules and use them for subnets and ports is that subnets and ports are actually top level API resources in neutron. They aren't actually childs of the network so using PARENT_OWNER for them could be missleading and confusing for users. Related-Bug: #2023679 [1] https://review.opendev.org/c/openstack/neutron/+/886231 Change-Id: I52fc92f76842f9f075e9e4c49262785ca099bdf8 --- neutron/conf/policies/base.py | 13 +++++++ neutron/conf/policies/port.py | 63 ++++++++++----------------------- neutron/conf/policies/subnet.py | 17 ++------- 3 files changed, 35 insertions(+), 58 deletions(-) diff --git a/neutron/conf/policies/base.py b/neutron/conf/policies/base.py index 395e4fd7f54..6947a3fbcd1 100644 --- a/neutron/conf/policies/base.py +++ b/neutron/conf/policies/base.py @@ -56,6 +56,19 @@ ADMIN_OR_PARENT_OWNER_MEMBER = ( ADMIN_OR_PARENT_OWNER_READER = ( '(' + ADMIN + ') or (' + PARENT_OWNER_READER + ')') +# Those rules related to the network owner are very similar (almost the same) +# as parent owner defined above. The only reason why they are kept here is that +# in case of some resources like ports or subnets neutron have got policies +# related to the "network owner" and network isn't really parent of the subnet +# or port. Because of that, using parent owner in those cases may be +# missleading for users so it's better to keep also "network owner" rules. +NET_OWNER_MEMBER = 'role:member and ' + RULE_NET_OWNER +NET_OWNER_READER = 'role:reader and ' + RULE_NET_OWNER +ADMIN_OR_NET_OWNER_MEMBER = ( + '(' + ADMIN + ') or (' + NET_OWNER_MEMBER + ')') +ADMIN_OR_NET_OWNER_READER = ( + '(' + ADMIN + ') or (' + NET_OWNER_READER + ')') + rules = [ policy.RuleDefault( diff --git a/neutron/conf/policies/port.py b/neutron/conf/policies/port.py index bce04da941c..f5ba1085ec9 100644 --- a/neutron/conf/policies/port.py +++ b/neutron/conf/policies/port.py @@ -66,9 +66,8 @@ rules = [ name='create_port:device_owner', check_str=neutron_policy.policy_or( 'not rule:network_device', - base.ADMIN, neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER + base.ADMIN_OR_NET_OWNER_MEMBER ), scope_types=['project'], description='Specify ``device_owner`` attribute when creating a port', @@ -86,8 +85,7 @@ rules = [ name='create_port:mac_address', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN), + base.ADMIN_OR_NET_OWNER_MEMBER), scope_types=['project'], description='Specify ``mac_address`` attribute when creating a port', operations=ACTION_POST, @@ -103,8 +101,7 @@ rules = [ name='create_port:fixed_ips', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN, + base.ADMIN_OR_NET_OWNER_MEMBER, 'rule:shared'), scope_types=['project'], description='Specify ``fixed_ips`` information when creating a port', @@ -122,8 +119,7 @@ rules = [ name='create_port:fixed_ips:ip_address', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN), + base.ADMIN_OR_NET_OWNER_MEMBER), scope_types=['project'], description='Specify IP address in ``fixed_ips`` when creating a port', operations=ACTION_POST, @@ -139,8 +135,7 @@ rules = [ name='create_port:fixed_ips:subnet_id', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN, + base.ADMIN_OR_NET_OWNER_MEMBER, 'rule:shared'), scope_types=['project'], description='Specify subnet ID in ``fixed_ips`` when creating a port', @@ -158,8 +153,7 @@ rules = [ name='create_port:port_security_enabled', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN), + base.ADMIN_OR_NET_OWNER_MEMBER), scope_types=['project'], description=( 'Specify ``port_security_enabled`` ' @@ -221,9 +215,7 @@ rules = [ ), policy.DocumentedRuleDefault( name='create_port:allowed_address_pairs', - check_str=neutron_policy.policy_or( - base.ADMIN, - base.RULE_NET_OWNER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description=( 'Specify ``allowed_address_pairs`` ' @@ -238,9 +230,7 @@ rules = [ ), policy.DocumentedRuleDefault( name='create_port:allowed_address_pairs:mac_address', - check_str=neutron_policy.policy_or( - base.ADMIN, - base.RULE_NET_OWNER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description=( 'Specify ``mac_address` of `allowed_address_pairs`` ' @@ -255,9 +245,7 @@ rules = [ ), policy.DocumentedRuleDefault( name='create_port:allowed_address_pairs:ip_address', - check_str=neutron_policy.policy_or( - base.ADMIN, - base.RULE_NET_OWNER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description=( 'Specify ``ip_address`` of ``allowed_address_pairs`` ' @@ -283,9 +271,8 @@ rules = [ policy.DocumentedRuleDefault( name='get_port', check_str=neutron_policy.policy_or( - base.ADMIN, neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, + base.ADMIN_OR_NET_OWNER_READER, base.PROJECT_READER ), scope_types=['project'], @@ -392,8 +379,7 @@ rules = [ check_str=neutron_policy.policy_or( 'not rule:network_device', neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN + base.ADMIN_OR_NET_OWNER_MEMBER, ), scope_types=['project'], description='Update ``device_owner`` attribute of a port', @@ -428,8 +414,7 @@ rules = [ name='update_port:fixed_ips', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN + base.ADMIN_OR_NET_OWNER_MEMBER, ), scope_types=['project'], description='Specify ``fixed_ips`` information when updating a port', @@ -446,8 +431,7 @@ rules = [ name='update_port:fixed_ips:ip_address', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN + base.ADMIN_OR_NET_OWNER_MEMBER, ), scope_types=['project'], description=( @@ -467,8 +451,7 @@ rules = [ name='update_port:fixed_ips:subnet_id', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN, + base.ADMIN_OR_NET_OWNER_MEMBER, 'rule:shared' ), scope_types=['project'], @@ -490,8 +473,7 @@ rules = [ name='update_port:port_security_enabled', check_str=neutron_policy.policy_or( neutron_policy.RULE_ADVSVC, - base.RULE_NET_OWNER, - base.ADMIN + base.ADMIN_OR_NET_OWNER_MEMBER, ), scope_types=['project'], description='Update ``port_security_enabled`` attribute of a port', @@ -548,9 +530,7 @@ rules = [ ), policy.DocumentedRuleDefault( name='update_port:allowed_address_pairs', - check_str=neutron_policy.policy_or( - base.ADMIN, - base.RULE_NET_OWNER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description='Update ``allowed_address_pairs`` attribute of a port', operations=ACTION_PUT, @@ -562,9 +542,7 @@ rules = [ ), policy.DocumentedRuleDefault( name='update_port:allowed_address_pairs:mac_address', - check_str=neutron_policy.policy_or( - base.ADMIN, - base.RULE_NET_OWNER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description=( 'Update ``mac_address`` of ``allowed_address_pairs`` ' @@ -579,9 +557,7 @@ rules = [ ), policy.DocumentedRuleDefault( name='update_port:allowed_address_pairs:ip_address', - check_str=neutron_policy.policy_or( - base.ADMIN, - base.RULE_NET_OWNER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description=( 'Update ``ip_address`` of ``allowed_address_pairs`` ' @@ -619,10 +595,9 @@ rules = [ policy.DocumentedRuleDefault( name='delete_port', check_str=neutron_policy.policy_or( - base.ADMIN, neutron_policy.RULE_ADVSVC, base.PROJECT_MEMBER, - base.RULE_NET_OWNER + base.ADMIN_OR_NET_OWNER_MEMBER ), scope_types=['project'], description='Delete a port', diff --git a/neutron/conf/policies/subnet.py b/neutron/conf/policies/subnet.py index cc3fdb1b48c..80ee4c152a5 100644 --- a/neutron/conf/policies/subnet.py +++ b/neutron/conf/policies/subnet.py @@ -36,18 +36,11 @@ ACTION_GET = [ {'method': 'GET', 'path': RESOURCE_PATH}, ] -# TODO(slaweq): remove it once network will be added to the -# EXT_PARENT_RESOURCE_MAPPING in neutron_lib and rule base.PARENT_OWNER_MEMBER -# will be possible to use instead of RULE_NET_OWNER_MEMBER -RULE_NET_OWNER_MEMBER = 'role:member and ' + base.RULE_NET_OWNER - rules = [ policy.DocumentedRuleDefault( name='create_subnet', - check_str=neutron_policy.policy_or( - base.ADMIN, - RULE_NET_OWNER_MEMBER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description='Create a subnet', operations=ACTION_POST, @@ -115,9 +108,7 @@ rules = [ ), policy.DocumentedRuleDefault( name='update_subnet', - check_str=neutron_policy.policy_or( - base.ADMIN_OR_PROJECT_MEMBER, - RULE_NET_OWNER_MEMBER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description='Update a subnet', operations=ACTION_PUT, @@ -153,9 +144,7 @@ rules = [ ), policy.DocumentedRuleDefault( name='delete_subnet', - check_str=neutron_policy.policy_or( - base.ADMIN_OR_PROJECT_MEMBER, - RULE_NET_OWNER_MEMBER), + check_str=base.ADMIN_OR_NET_OWNER_MEMBER, scope_types=['project'], description='Delete a subnet', operations=ACTION_DELETE,