Files
neutron/neutron/conf/policies/subnet.py
Tobias Urdin 65b9dc622f Allow service role more RBAC access for Octavia
This updates the default RBAC rules for multiple
resources to allow for a seamless integration with
Octavia without having to give Octavia system scope
admin in the entire cloud.

The current use of the service role in the RBAC
rules allows for pretty much all of the permissions
that Octavia needs today except for a few.

It needs get_subnet to be able to retrieve a subnet
and check the details, this is low impact as we
already allow get_network.

It also needs get_network_ip_availability because it
supports to automatically select a subnet (if none
is given) on a network based on the amount of
available IP addresses.

The default Amphora compute driver for Octavia uses
a keepalived and HAProxy implementation that uses
unicast VRRP for the VIP address, this VIP address
is added as an allowed address pair on the ports
for the amphora compute instances so the VIP port
itself is not bound.

Octavia also depends on being able to populate the
``device_id`` field on a port which means it also
needs this patch [1] together with this one.

[1] https://review.opendev.org/c/openstack/neutron/+/947003

Closes-Bug: #2105502
Change-Id: I089999cece698af1a3b54d1341d9004d4108ae44
2025-05-06 00:47:56 +00:00

272 lines
9.4 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from neutron_lib import policy as neutron_policy
from oslo_log import versionutils
from oslo_policy import policy
from neutron.conf.policies import base
DEPRECATED_REASON = (
"The subnet API now supports system scope and default roles.")
COLLECTION_PATH = '/subnets'
RESOURCE_PATH = '/subnets/{id}'
TAGS_PATH = RESOURCE_PATH + '/tags'
TAG_PATH = RESOURCE_PATH + '/tags/{tag_id}'
ACTION_POST = [
{'method': 'POST', 'path': COLLECTION_PATH},
]
ACTION_PUT = [
{'method': 'PUT', 'path': RESOURCE_PATH},
]
ACTION_DELETE = [
{'method': 'DELETE', 'path': RESOURCE_PATH},
]
ACTION_GET = [
{'method': 'GET', 'path': COLLECTION_PATH},
{'method': 'GET', 'path': RESOURCE_PATH},
]
ACTION_GET_TAGS = [
{'method': 'GET', 'path': TAGS_PATH},
{'method': 'GET', 'path': TAG_PATH},
]
ACTION_PUT_TAGS = [
{'method': 'PUT', 'path': TAGS_PATH},
{'method': 'PUT', 'path': TAG_PATH},
]
ACTION_POST_TAGS = [
{'method': 'POST', 'path': TAGS_PATH},
]
ACTION_DELETE_TAGS = [
{'method': 'DELETE', 'path': TAGS_PATH},
{'method': 'DELETE', 'path': TAG_PATH},
]
rules = [
policy.RuleDefault(
name='external_network',
check_str='field:subnets:router:external=True',
description='Definition of a subnet that belongs to an external '
'network'
),
policy.DocumentedRuleDefault(
name='create_subnet',
check_str=base.ADMIN_OR_NET_OWNER_MEMBER,
scope_types=['project'],
description='Create a subnet',
operations=ACTION_POST,
deprecated_rule=policy.DeprecatedRule(
name='create_subnet',
check_str=neutron_policy.RULE_ADMIN_OR_NET_OWNER,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='create_subnet:segment_id',
check_str=base.ADMIN,
scope_types=['project'],
description=(
'Specify ``segment_id`` attribute when creating a subnet'
),
operations=ACTION_POST,
deprecated_rule=policy.DeprecatedRule(
name='create_subnet:segment_id',
check_str=neutron_policy.RULE_ADMIN_ONLY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='create_subnet:service_types',
check_str=base.ADMIN,
scope_types=['project'],
description=(
'Specify ``service_types`` attribute when creating a subnet'
),
operations=ACTION_POST,
deprecated_rule=policy.DeprecatedRule(
name='create_subnet:service_types',
check_str=neutron_policy.RULE_ADMIN_ONLY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='create_subnet:tags',
check_str=neutron_policy.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_NET_OWNER_MEMBER,
),
scope_types=['project'],
description='Create the subnet tags',
operations=ACTION_POST_TAGS,
deprecated_rule=policy.DeprecatedRule(
name='create_subnets_tags',
check_str=neutron_policy.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_NET_OWNER_MEMBER,
),
deprecated_reason="Name of the rule is changed.",
deprecated_since="2025.1")
),
policy.DocumentedRuleDefault(
name='get_subnet',
check_str=neutron_policy.policy_or(
base.PROJECT_READER,
'rule:shared',
'rule:external_network',
base.ADMIN_OR_NET_OWNER_READER,
base.SERVICE,
),
scope_types=['project'],
description='Get a subnet',
operations=ACTION_GET,
deprecated_rule=policy.DeprecatedRule(
name='get_subnet',
check_str=neutron_policy.policy_or(
'rule:shared',
'rule:external_network',
neutron_policy.RULE_ADMIN_OR_OWNER,
),
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='get_subnet:segment_id',
check_str=base.ADMIN,
scope_types=['project'],
description='Get ``segment_id`` attribute of a subnet',
operations=ACTION_GET,
deprecated_rule=policy.DeprecatedRule(
name='get_subnet:segment_id',
check_str=neutron_policy.RULE_ADMIN_ONLY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='get_subnet:tags',
check_str=neutron_policy.policy_or(
base.PROJECT_READER,
'rule:shared',
'rule:external_network',
base.ADMIN_OR_NET_OWNER_READER,
),
scope_types=['project'],
description='Get the subnet tags',
operations=ACTION_GET_TAGS,
deprecated_rule=policy.DeprecatedRule(
name='get_subnets_tags',
check_str=neutron_policy.policy_or(
base.PROJECT_READER,
'rule:shared',
'rule:external_network',
base.ADMIN_OR_NET_OWNER_READER,
),
deprecated_reason="Name of the rule is changed.",
deprecated_since="2025.1")
),
policy.DocumentedRuleDefault(
name='update_subnet',
check_str=neutron_policy.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_NET_OWNER_MEMBER),
scope_types=['project'],
description='Update a subnet',
operations=ACTION_PUT,
deprecated_rule=policy.DeprecatedRule(
name='update_subnet',
check_str=neutron_policy.RULE_ADMIN_OR_NET_OWNER,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='update_subnet:segment_id',
check_str=base.ADMIN,
scope_types=['project'],
description='Update ``segment_id`` attribute of a subnet',
operations=ACTION_PUT,
deprecated_rule=policy.DeprecatedRule(
name='update_subnet:segment_id',
check_str=neutron_policy.RULE_ADMIN_ONLY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='update_subnet:service_types',
check_str=base.ADMIN,
scope_types=['project'],
description='Update ``service_types`` attribute of a subnet',
operations=ACTION_PUT,
deprecated_rule=policy.DeprecatedRule(
name='update_subnet:service_types',
check_str=neutron_policy.RULE_ADMIN_ONLY,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='update_subnet:tags',
check_str=neutron_policy.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_NET_OWNER_MEMBER,
),
scope_types=['project'],
description='Update the subnet tags',
operations=ACTION_PUT_TAGS,
deprecated_rule=policy.DeprecatedRule(
name='update_subnets_tags',
check_str=neutron_policy.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_NET_OWNER_MEMBER,
),
deprecated_reason="Name of the rule is changed.",
deprecated_since="2025.1")
),
policy.DocumentedRuleDefault(
name='delete_subnet',
check_str=neutron_policy.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_NET_OWNER_MEMBER,
),
scope_types=['project'],
description='Delete a subnet',
operations=ACTION_DELETE,
deprecated_rule=policy.DeprecatedRule(
name='delete_subnet',
check_str=neutron_policy.RULE_ADMIN_OR_NET_OWNER,
deprecated_reason=DEPRECATED_REASON,
deprecated_since=versionutils.deprecated.WALLABY)
),
policy.DocumentedRuleDefault(
name='delete_subnet:tags',
check_str=neutron_policy.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_NET_OWNER_MEMBER,
),
scope_types=['project'],
description='Delete the subnet tags',
operations=ACTION_DELETE_TAGS,
deprecated_rule=policy.DeprecatedRule(
name='delete_subnets_tags',
check_str=neutron_policy.policy_or(
base.PROJECT_MEMBER,
base.ADMIN_OR_NET_OWNER_MEMBER,
),
deprecated_reason="Name of the rule is changed.",
deprecated_since="2025.1")
),
]
def list_rules():
return rules