ironic/ironic/common/policy.py
Julia Kreger 0313ce26b5 Fix service role support
Turns out the service role support doesn't quite work,
because you could not enumerate nodes regardless of node
owner or lessee in order to enable services like Nova to
enumerate nodes to be able to schedule upon them, or
networking-baremetal to enumerate ports in update mapping
in Neutron.

So this change enables permissions to be modified to allow
service project users with the service role to enumerate the
list of resources, and grants rights similar to "system scoped
members" to the service project's users with the "service" role
which aligns with update actions to provision/unprovision nodes.

Adds some additional rbac testing to ensure we appropriately
covered these access rights.

Closes-Bug: 2051592
Change-Id: I2b4bcc748b6e43e4215dc45137becce301349032
2024-01-31 15:27:57 -08:00

2021 lines
80 KiB
Python

# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# 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.
"""Policy Engine For Ironic."""
import itertools
import sys
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log
from oslo_log import versionutils
from oslo_policy import opts
from oslo_policy import policy
from ironic.common import exception
_ENFORCER = None
CONF = cfg.CONF
LOG = log.getLogger(__name__)
# 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
DEFAULT_POLICY_FILE = 'policy.yaml'
opts.set_defaults(cfg.CONF, DEFAULT_POLICY_FILE,
enforce_scope=True,
enforce_new_defaults=True)
# Generic policy check string for system administrators. These are the people
# who need the highest level of authorization to operate the deployment.
# They're allowed to create, read, update, or delete any system-specific
# resource. They can also operate on project-specific resources where
# applicable (e.g., cleaning up baremetal hosts)
SYSTEM_ADMIN = 'role:admin and system_scope:all'
# Generic policy check string for system users who don't require all the
# authorization that system administrators typically have. This persona, or
# check string, typically isn't used by default, but it's existence it useful
# in the event a deployment wants to offload some administrative action from
# system administrator to system members.
# The rule:service_role match here is to enable an elevated level of API
# access for a specialized service role and users with appropriate
# service role access.
SYSTEM_MEMBER = '(role:member and system_scope:all) or rule:service_role' # noqa
# Generic policy check string for read-only access to system-level
# resources. This persona is useful for someone who needs access
# for auditing or even support. These uses are also able to view
# project-specific resources where applicable (e.g., listing all
# volumes in the deployment, regardless of the project they belong to).
# The rule:service_role match here is to enable an elevated level of API
# access for a specialized service role and users with appropriate
# role access, specifically because 'service" role is outside of the RBAC
# model defaults and does not imply reader access.
SYSTEM_READER = '(role:reader and system_scope:all) or (role:service and system_scope:all) or rule:service_role' # noqa
# This check string is reserved for actions that require the highest level of
# authorization on a project or resources within the project (e.g., setting the
# default volume type for a project)
PROJECT_ADMIN = ('role:admin and '
'project_id:%(node.owner)s')
# This check string is reserved for an intermediate point between
# a Project Admin and a Project Member. This is an outcome of the
# revised Yoga Secure RBAC community goal.
# The advantage here may be that this rule *does* match against node owners
# and lessees.
PROJECT_MANAGER = ('role:manager and '
'(project_id:%(node.owner)s or project_id:%(node.lessee)s)')
# This check string is the primary use case for typical end-users, who are
# working with resources that belong to a project (e.g., creating volumes and
# backups).
PROJECT_MEMBER = ('role:member and '
'(project_id:%(node.owner)s or project_id:%(node.lessee)s)')
# This check string should only be used to protect read-only project-specific
# resources. It should not be used to protect APIs that make writable changes
# (e.g., updating a volume or deleting a backup).
PROJECT_READER = ('role:reader and '
'(project_id:%(node.owner)s or project_id:%(node.lessee)s)')
# This check string is used for granting access to other services which need
# to communicate with Ironic, for example, Nova-Compute to provision nodes,
# or Ironic-Inspector to create nodes. The idea behind a service role is
# one which has restricted access to perform operations, that are limited
# to remote automated and inter-operation processes.
SYSTEM_SERVICE = ('role:service and system_scope:all')
PROJECT_SERVICE = ('role:service and project_id:%(node.owner)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 baremetal host in the deployment,
# a project member should only be able to delete hosts in their project).
SYSTEM_OR_PROJECT_MEMBER = (
'(' + SYSTEM_MEMBER + ') or (' + PROJECT_MEMBER + ') or (' + SYSTEM_SERVICE + ')' # noqa
)
SYSTEM_OR_PROJECT_READER = (
'(' + SYSTEM_READER + ') or (' + PROJECT_READER + ') or (' + PROJECT_SERVICE + ')' # noqa
)
PROJECT_OWNER_ADMIN = ('role:admin and project_id:%(node.owner)s')
PROJECT_OWNER_MANAGER = ('role:manager and project_id:%(node.owner)s')
PROJECT_OWNER_MEMBER = ('role:member and project_id:%(node.owner)s')
PROJECT_OWNER_READER = ('role:reader and project_id:%(node.owner)s')
PROJECT_LESSEE_ADMIN = ('role:admin and project_id:%(node.lessee)s')
PROJECT_LESSEE_MANAGER = ('role:manager and project_id:%(node.lessee)s')
# Not used - Members can create/destroy their allocations.
ALLOCATION_OWNER_ADMIN = ('role:admin and project_id:%(allocation.owner)s')
# Not used - Members can create/destroy their allocations.
ALLOCATION_OWNER_MANAGER = ('role:manager and project_id:%(allocation.owner)s')
ALLOCATION_OWNER_MEMBER = ('role:member and project_id:%(allocation.owner)s')
ALLOCATION_OWNER_READER = ('role:reader and project_id:%(allocation.owner)s')
# Used for general operations like changing provision state.
SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN = (
'(' + SYSTEM_MEMBER + ') or (' + SYSTEM_SERVICE + ') or (' + PROJECT_OWNER_MEMBER + ') or (' + PROJECT_LESSEE_ADMIN + ') or (' + PROJECT_LESSEE_MANAGER + ') or (' + PROJECT_SERVICE + ')' # noqa
)
# Used for creation and deletion of network ports.
SYSTEM_ADMIN_OR_OWNER_ADMIN = (
'(' + SYSTEM_ADMIN + ') or (' + SYSTEM_SERVICE + ') or (' + PROJECT_OWNER_ADMIN + ') or (' + PROJECT_OWNER_MANAGER + ') or (' + PROJECT_SERVICE + ')' # noqa
)
# Used to map system members, and owner admins to the same access rights.
# This is actions such as update driver interfaces, delete ports.
SYSTEM_MEMBER_OR_OWNER_ADMIN = (
'(' + SYSTEM_MEMBER + ') or (' + SYSTEM_SERVICE + ') or (' + PROJECT_OWNER_ADMIN + ') or (' + PROJECT_OWNER_MANAGER + ') or (' + PROJECT_SERVICE + ')' # noqa
)
# Used to map "member" only rights, i.e. those of "users using a deployment"
SYSTEM_MEMBER_OR_OWNER_MEMBER = (
'(' + SYSTEM_MEMBER + ') or (' + SYSTEM_SERVICE + ') or (' + PROJECT_OWNER_MEMBER + ') or (' + PROJECT_SERVICE + ')' # noqa
)
# Used throughout to map where authenticated readers
# should be able to read API objects.
SYSTEM_OR_OWNER_READER = (
'(' + SYSTEM_READER + ') or (' + SYSTEM_SERVICE + ') or (' + PROJECT_OWNER_READER + ') or (' + PROJECT_SERVICE + ')' # noqa
)
# Mainly used for targets/connectors
SYSTEM_MEMBER_OR_OWNER_LESSEE_ADMIN = (
'(' + SYSTEM_MEMBER + ') or (' + SYSTEM_SERVICE + ') or (' + PROJECT_OWNER_ADMIN + ') or (' + PROJECT_OWNER_MANAGER + ') or (' + PROJECT_LESSEE_ADMIN + ') or (' + PROJECT_LESSEE_MANAGER + ') or (' + PROJECT_SERVICE + ')' # noqa
)
# The system has rights to manage the allocations for users, in a sense
# a delegated management since they are not creating a real object or asset,
# but allocations of assets.
ALLOCATION_MEMBER = (
'(' + SYSTEM_MEMBER + ') or (' + ALLOCATION_OWNER_MEMBER + ')'
)
ALLOCATION_READER = (
'(' + SYSTEM_READER + ') or (' + ALLOCATION_OWNER_READER + ')'
)
ALLOCATION_CREATOR = (
'(' + SYSTEM_MEMBER + ') or (role:member)'
)
# Special purpose aliases for things like "ability to access the API
# as a reader, or permission checking that does not require node
# owner relationship checking
API_READER = ('(role:reader) or (role:service)')
# Used for ability to view target properties of a volume, which is
# considered highly restricted.
TARGET_PROPERTIES_READER = (
'(' + SYSTEM_READER + ') or (role:admin)'
)
pre_rbac_deprecated_reason = 'Pre-RBAC default rule. This rule does not support scoping system scoping and as such is deprecated.' # noqa
default_policies = [
# Legacy setting, don't remove. Likely to be overridden by operators who
# forget to update their policy.json configuration file.
# This gets rolled into the new "is_admin" rule below.
policy.RuleDefault('admin_api',
'role:admin or role:administrator',
description='Legacy rule for cloud admin access',
deprecated_for_removal=True,
deprecated_since=versionutils.deprecated.WALLABY,
deprecated_reason=pre_rbac_deprecated_reason
),
# is_public_api is set in the environment from AuthPublicRoutes
# TODO(TheJulia): Once legacy policy rules are removed, is_public_api
# can be removed from the code base.
policy.RuleDefault('public_api',
'is_public_api:True',
description='Internal flag for public API routes'),
# Generic default to hide passwords in node driver_info
# NOTE(tenbrae): the 'show_password' policy setting hides secrets in
# driver_info. However, the name exists for legacy
# purposes and can not be changed. Changing it will cause
# upgrade problems for any operators who have customized
# the value of this field
policy.RuleDefault('show_password',
'!',
description='Show or mask secrets within node driver information in API responses'), # noqa
# Generic default to hide instance secrets
policy.RuleDefault('show_instance_secrets',
'!',
description='Show or mask secrets within instance information in API responses'), # noqa
# NOTE(TheJulia): This is a special rule to allow customization of the
# service role check. The config.service_project_name is a reserved
# target check field which is loaded from configuration to the
# check context in ironic/common/context.py.
policy.RuleDefault('service_role',
'role:service and project_name:%(config.service_project_name)s', # noqa
description='Rule to match service role usage with a service project, delineated as a separate rule to enable customization.'), # noqa
# Roles likely to be overridden by operator
# TODO(TheJulia): Lets nuke demo from high orbit.
policy.RuleDefault('is_member',
'(project_domain_id:default or project_domain_id:None) and (project_name:demo or project_name:baremetal)', # noqa
description='May be used to restrict access to specific projects', # noqa
deprecated_for_removal=True,
deprecated_since=versionutils.deprecated.WALLABY,
deprecated_reason=pre_rbac_deprecated_reason),
policy.RuleDefault('is_observer',
'rule:is_member and (role:observer or role:baremetal_observer)', # noqa
description='Read-only API access',
deprecated_for_removal=True,
deprecated_since=versionutils.deprecated.WALLABY,
deprecated_reason=pre_rbac_deprecated_reason),
policy.RuleDefault('is_admin',
'rule:admin_api or (rule:is_member and role:baremetal_admin)', # noqa
description='Full read/write API access',
deprecated_for_removal=True,
deprecated_since=versionutils.deprecated.WALLABY,
deprecated_reason=pre_rbac_deprecated_reason),
policy.RuleDefault('is_node_owner',
'project_id:%(node.owner)s',
description='Owner of node',
deprecated_for_removal=True,
deprecated_since=versionutils.deprecated.WALLABY,
deprecated_reason=pre_rbac_deprecated_reason),
policy.RuleDefault('is_node_lessee',
'project_id:%(node.lessee)s',
description='Lessee of node',
deprecated_for_removal=True,
deprecated_since=versionutils.deprecated.WALLABY,
deprecated_reason=pre_rbac_deprecated_reason),
policy.RuleDefault('is_allocation_owner',
'project_id:%(allocation.owner)s',
description='Owner of allocation',
deprecated_for_removal=True,
deprecated_since=versionutils.deprecated.WALLABY,
deprecated_reason=pre_rbac_deprecated_reason),
]
# NOTE(tenbrae): to follow policy-in-code spec, we define defaults for
# the granular policies in code, rather than in policy.json.
# All of these may be overridden by configuration, but we can
# depend on their existence throughout the code.
# TODO(TheJulia): Since the OpenStack community appears to be
# coalescing around taking a very long term deprecation path,
# and is actually seeking to suppress the warnings being generated
# for the time being, I've changed the warning below to remove
# reference to the Xena cycle. This should be changed once we
# determine when the old policies will be fully removed.
deprecated_node_reason = """
The baremetal node API is now aware of system scope and default roles.
Capability to fallback to legacy admin project policy configuration
will be removed in a future release of Ironic.
"""
deprecated_node_create = policy.DeprecatedRule(
name='baremetal:node:create',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_get = policy.DeprecatedRule(
name='baremetal:node:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_list = policy.DeprecatedRule(
name='baremetal:node:list',
check_str='rule:baremetal:node:get',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_list_all = policy.DeprecatedRule(
name='baremetal:node:list_all',
check_str='rule:baremetal:node:get',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_update = policy.DeprecatedRule(
name='baremetal:node:update',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_update_extra = policy.DeprecatedRule(
name='baremetal:node:update_extra',
check_str='rule:baremetal:node:update',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_update_instance_info = policy.DeprecatedRule(
name='baremetal:node:update_instance_info',
check_str='rule:baremetal:node:update',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_update_owner_provisioned = policy.DeprecatedRule(
name='baremetal:node:update_owner_provisioned',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_delete = policy.DeprecatedRule(
name='baremetal:node:delete',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_validate = policy.DeprecatedRule(
name='baremetal:node:validate',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_set_maintenance = policy.DeprecatedRule(
name='baremetal:node:set_maintenance',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_clear_maintenance = policy.DeprecatedRule(
name='baremetal:node:clear_maintenance',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_get_boot_device = policy.DeprecatedRule(
name='baremetal:node:get_boot_device',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_set_boot_device = policy.DeprecatedRule(
name='baremetal:node:set_boot_device',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_get_indicator_state = policy.DeprecatedRule(
name='baremetal:node:get_indicator_state',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_set_indicator_state = policy.DeprecatedRule(
name='baremetal:node:set_indicator_state',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_inject_nmi = policy.DeprecatedRule(
name='baremetal:node:inject_nmi',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_get_states = policy.DeprecatedRule(
name='baremetal:node:get_states',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_set_power_state = policy.DeprecatedRule(
name='baremetal:node:set_power_state',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_set_provision_state = policy.DeprecatedRule(
name='baremetal:node:set_provision_state',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_set_raid_state = policy.DeprecatedRule(
name='baremetal:node:set_raid_state',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_get_console = policy.DeprecatedRule(
name='baremetal:node:get_console',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_set_console_state = policy.DeprecatedRule(
name='baremetal:node:set_console_state',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_vif_list = policy.DeprecatedRule(
name='baremetal:node:vif:list',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_vif_attach = policy.DeprecatedRule(
name='baremetal:node:vif:attach',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_vif_detach = policy.DeprecatedRule(
name='baremetal:node:vif:detach',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_traits_list = policy.DeprecatedRule(
name='baremetal:node:traits:list',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_traits_set = policy.DeprecatedRule(
name='baremetal:node:traits:set',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_traits_delete = policy.DeprecatedRule(
name='baremetal:node:traits:delete',
check_str='rule:is_admin',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_node_bios_get = policy.DeprecatedRule(
name='baremetal:node:bios:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_bios_disable_cleaning = policy.DeprecatedRule(
name='baremetal:node:disable_cleaning',
check_str='rule:baremetal:node:update',
deprecated_reason=deprecated_node_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
node_policies = [
policy.DocumentedRuleDefault(
name='baremetal:node:create',
check_str='(' + SYSTEM_ADMIN + ') or (' + SYSTEM_SERVICE + ')',
scope_types=['system', 'project'],
description='Create Node records',
operations=[{'path': '/nodes', 'method': 'POST'}],
deprecated_rule=deprecated_node_create
),
policy.DocumentedRuleDefault(
name='baremetal:node:create:self_owned_node',
check_str=('(role:admin) or (role:service)'),
scope_types=['system', 'project'],
description='Create node records which will be tracked '
'as owned by the associated user project.',
operations=[{'path': '/nodes', 'method': 'POST'}],
),
policy.DocumentedRuleDefault(
name='baremetal:node:list',
check_str=API_READER,
scope_types=['system', 'project'],
description='Retrieve multiple Node records, filtered by '
'an explicit owner or the client project_id',
operations=[{'path': '/nodes', 'method': 'GET'},
{'path': '/nodes/detail', 'method': 'GET'}],
deprecated_rule=deprecated_node_list
),
policy.DocumentedRuleDefault(
name='baremetal:node:list_all',
check_str=SYSTEM_READER,
scope_types=['system', 'project'],
description='Retrieve multiple Node records',
operations=[{'path': '/nodes', 'method': 'GET'},
{'path': '/nodes/detail', 'method': 'GET'}],
deprecated_rule=deprecated_node_list_all
),
policy.DocumentedRuleDefault(
name='baremetal:node:get',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Retrieve a single Node record',
operations=[{'path': '/nodes/{node_ident}', 'method': 'GET'}],
deprecated_rule=deprecated_node_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:get:filter_threshold',
check_str=SYSTEM_READER,
scope_types=['system', 'project'],
description='Filter to allow operators to govern the threshold '
'where information should be filtered. Non-authorized '
'users will be subjected to additional API policy '
'checks for API content response bodies.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'GET'}],
# This rule fallsback to deprecated_node_get in order to provide a
# mechanism so the additional policies only engage in an updated
# operating context.
deprecated_rule=deprecated_node_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:get:last_error',
check_str=SYSTEM_OR_OWNER_READER,
scope_types=['system', 'project'],
description='Governs if the node last_error field is masked from API '
'clients with insufficient privileges.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'GET'}],
deprecated_rule=deprecated_node_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:get:reservation',
check_str=SYSTEM_OR_OWNER_READER,
scope_types=['system', 'project'],
description='Governs if the node reservation field is masked from API '
'clients with insufficient privileges.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'GET'}],
deprecated_rule=deprecated_node_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:get:driver_internal_info',
check_str=SYSTEM_OR_OWNER_READER,
scope_types=['system', 'project'],
description='Governs if the node driver_internal_info field is '
'masked from API clients with insufficient privileges.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'GET'}],
deprecated_rule=deprecated_node_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:get:driver_info',
check_str=SYSTEM_OR_OWNER_READER,
scope_types=['system', 'project'],
description='Governs if the driver_info field is masked from API '
'clients with insufficient privileges.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'GET'}],
deprecated_rule=deprecated_node_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:driver_info',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Governs if node driver_info field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:properties',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Governs if node properties field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:chassis_uuid',
check_str=SYSTEM_ADMIN,
scope_types=['system', 'project'],
description='Governs if node chassis_uuid field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:instance_uuid',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Governs if node instance_uuid field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:lessee',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Governs if node lessee field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:owner',
check_str=SYSTEM_MEMBER,
scope_types=['system', 'project'],
description='Governs if node owner field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:driver_interfaces',
check_str=SYSTEM_MEMBER_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Governs if node driver and driver interfaces field '
'can be updated via the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:network_data',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Governs if node driver_info field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:conductor_group',
check_str=SYSTEM_MEMBER,
scope_types=['system', 'project'],
description='Governs if node conductor_group field can be updated '
'via the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:name',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Governs if node name field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:retired',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Governs if node retired and retired reason '
'can be updated by API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
# If this role is denied we should likely roll into the other rules
# Like, this rule could match "SYSTEM_MEMBER" by default and then drill
# further into each field, which would maintain what we do today, and
# enable further testing.
policy.DocumentedRuleDefault(
name='baremetal:node:update',
check_str=SYSTEM_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Generalized update of node records',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update
),
policy.DocumentedRuleDefault(
name='baremetal:node:update_extra',
check_str=SYSTEM_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Update Node extra field',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update_extra
),
policy.DocumentedRuleDefault(
name='baremetal:node:update_instance_info',
check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Update Node instance_info field',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update_instance_info
),
policy.DocumentedRuleDefault(
name='baremetal:node:update_owner_provisioned',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Update Node owner even when Node is provisioned',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
deprecated_rule=deprecated_node_update_owner_provisioned
),
policy.DocumentedRuleDefault(
name='baremetal:node:delete',
check_str=SYSTEM_ADMIN,
scope_types=['system', 'project'],
description='Delete Node records',
operations=[{'path': '/nodes/{node_ident}', 'method': 'DELETE'}],
deprecated_rule=deprecated_node_delete
),
policy.DocumentedRuleDefault(
name='baremetal:node:delete:self_owned_node',
check_str=PROJECT_ADMIN,
scope_types=['system', 'project'],
description='Delete node records which are associated with '
'the requesting project.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'DELETE'}],
),
policy.DocumentedRuleDefault(
name='baremetal:node:validate',
check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Request active validation of Nodes',
operations=[
{'path': '/nodes/{node_ident}/validate', 'method': 'GET'}
],
deprecated_rule=deprecated_node_validate
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_maintenance',
check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Set maintenance flag, taking a Node out of service',
operations=[
{'path': '/nodes/{node_ident}/maintenance', 'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_maintenance
),
policy.DocumentedRuleDefault(
name='baremetal:node:clear_maintenance',
check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN,
scope_types=['system', 'project'],
description=(
'Clear maintenance flag, placing the Node into service again'
),
operations=[
{'path': '/nodes/{node_ident}/maintenance', 'method': 'DELETE'}
],
deprecated_rule=deprecated_node_clear_maintenance
),
# NOTE(TheJulia): This should liekly be deprecated and be replaced with
# a cached object.
policy.DocumentedRuleDefault(
name='baremetal:node:get_boot_device',
check_str=SYSTEM_MEMBER_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Retrieve Node boot device metadata',
operations=[
{'path': '/nodes/{node_ident}/management/boot_device',
'method': 'GET'},
{'path': '/nodes/{node_ident}/management/boot_device/supported',
'method': 'GET'}
],
deprecated_rule=deprecated_node_get_boot_device
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_boot_device',
check_str=SYSTEM_MEMBER_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Change Node boot device',
operations=[
{'path': '/nodes/{node_ident}/management/boot_device',
'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_maintenance
),
policy.DocumentedRuleDefault(
name='baremetal:node:get_indicator_state',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Retrieve Node indicators and their states',
operations=[
{'path': '/nodes/{node_ident}/management/indicators/'
'{component}/{indicator}',
'method': 'GET'},
{'path': '/nodes/{node_ident}/management/indicators',
'method': 'GET'}
],
deprecated_rule=deprecated_node_get_indicator_state
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_indicator_state',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Change Node indicator state',
operations=[
{'path': '/nodes/{node_ident}/management/indicators/'
'{component}/{indicator}',
'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_indicator_state
),
policy.DocumentedRuleDefault(
name='baremetal:node:inject_nmi',
check_str=SYSTEM_MEMBER_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Inject NMI for a node',
operations=[
{'path': '/nodes/{node_ident}/management/inject_nmi',
'method': 'PUT'}
],
deprecated_rule=deprecated_node_inject_nmi
),
policy.DocumentedRuleDefault(
name='baremetal:node:get_states',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='View Node power and provision state',
operations=[{'path': '/nodes/{node_ident}/states', 'method': 'GET'}],
deprecated_rule=deprecated_node_get_states
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_power_state',
check_str=SYSTEM_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Change Node power status',
operations=[
{'path': '/nodes/{node_ident}/states/power', 'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_power_state
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_boot_mode',
check_str=SYSTEM_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Change Node boot mode',
operations=[
{'path': '/nodes/{node_ident}/states/boot_mode', 'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_power_state
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_secure_boot',
check_str=SYSTEM_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Change Node secure boot state',
operations=[
{'path': '/nodes/{node_ident}/states/secure_boot', 'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_power_state
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_provision_state',
check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Change Node provision status',
operations=[
{'path': '/nodes/{node_ident}/states/provision', 'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_provision_state
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_raid_state',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Change Node RAID status',
operations=[
{'path': '/nodes/{node_ident}/states/raid', 'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_raid_state
),
policy.DocumentedRuleDefault(
name='baremetal:node:get_console',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Get Node console connection information',
operations=[
{'path': '/nodes/{node_ident}/states/console', 'method': 'GET'}
],
deprecated_rule=deprecated_node_get_console
),
policy.DocumentedRuleDefault(
name='baremetal:node:set_console_state',
check_str=SYSTEM_MEMBER_OR_OWNER_MEMBER,
scope_types=['system', 'project'],
description='Change Node console status',
operations=[
{'path': '/nodes/{node_ident}/states/console', 'method': 'PUT'}
],
deprecated_rule=deprecated_node_set_console_state
),
policy.DocumentedRuleDefault(
name='baremetal:node:vif:list',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='List VIFs attached to node',
operations=[{'path': '/nodes/{node_ident}/vifs', 'method': 'GET'}],
deprecated_rule=deprecated_node_vif_list
),
policy.DocumentedRuleDefault(
name='baremetal:node:vif:attach',
check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Attach a VIF to a node',
operations=[{'path': '/nodes/{node_ident}/vifs', 'method': 'POST'}],
deprecated_rule=deprecated_node_vif_attach
),
policy.DocumentedRuleDefault(
name='baremetal:node:vif:detach',
check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Detach a VIF from a node',
operations=[
{'path': '/nodes/{node_ident}/vifs/{node_vif_ident}',
'method': 'DELETE'}
],
deprecated_rule=deprecated_node_vif_detach
),
policy.DocumentedRuleDefault(
name='baremetal:node:traits:list',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='List node traits',
operations=[{'path': '/nodes/{node_ident}/traits', 'method': 'GET'}],
deprecated_rule=deprecated_node_traits_list
),
policy.DocumentedRuleDefault(
name='baremetal:node:traits:set',
check_str=SYSTEM_MEMBER_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Add a trait to, or replace all traits of, a node',
operations=[
{'path': '/nodes/{node_ident}/traits', 'method': 'PUT'},
{'path': '/nodes/{node_ident}/traits/{trait}', 'method': 'PUT'}
],
deprecated_rule=deprecated_node_traits_set
),
policy.DocumentedRuleDefault(
name='baremetal:node:traits:delete',
check_str=SYSTEM_MEMBER_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Remove one or all traits from a node',
operations=[
{'path': '/nodes/{node_ident}/traits', 'method': 'DELETE'},
{'path': '/nodes/{node_ident}/traits/{trait}',
'method': 'DELETE'}
],
deprecated_rule=deprecated_node_traits_delete
),
policy.DocumentedRuleDefault(
name='baremetal:node:bios:get',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Retrieve Node BIOS information',
operations=[
{'path': '/nodes/{node_ident}/bios', 'method': 'GET'},
{'path': '/nodes/{node_ident}/bios/{setting}', 'method': 'GET'}
],
deprecated_rule=deprecated_node_bios_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:disable_cleaning',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Disable Node disk cleaning',
operations=[
{'path': '/nodes/{node_ident}', 'method': 'PATCH'}
],
deprecated_rule=deprecated_bios_disable_cleaning
),
policy.DocumentedRuleDefault(
name='baremetal:node:history:get',
check_str=SYSTEM_OR_OWNER_READER,
scope_types=['system', 'project'],
description='Filter to allow operators to retreive history records '
'for a node.',
operations=[
{'path': '/nodes/{node_ident}/history', 'method': 'GET'},
{'path': '/nodes/{node_ident}/history/{event_ident}',
'method': 'GET'}
],
# This rule fallsback to deprecated_node_get in order to provide a
# mechanism so the additional policies only engage in an updated
# operating context.
deprecated_rule=deprecated_node_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:inventory:get',
check_str=SYSTEM_OR_OWNER_READER,
scope_types=['system', 'project'],
description='Retrieve introspection data for a node.',
operations=[
{'path': '/nodes/{node_ident}/inventory', 'method': 'GET'},
],
# This rule fallsback to deprecated_node_get in order to provide a
# mechanism so the additional policies only engage in an updated
# operating context.
deprecated_rule=deprecated_node_get
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:shard',
check_str=SYSTEM_ADMIN,
scope_types=['system', 'project'],
description='Governs if node shard field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
),
policy.DocumentedRuleDefault(
name='baremetal:shards:get',
check_str=SYSTEM_READER,
scope_types=['system', 'project'],
description='Governs if shards can be read via the API clients.',
operations=[{'path': '/shards', 'method': 'GET'}],
),
policy.DocumentedRuleDefault(
name='baremetal:node:update:parent_node',
check_str=SYSTEM_MEMBER,
scope_types=['system', 'project'],
description='Governs if node parent_node field can be updated via '
'the API clients.',
operations=[{'path': '/nodes/{node_ident}', 'method': 'PATCH'}],
),
policy.DocumentedRuleDefault(
name='baremetal:node:firmware:get',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Retrieve Node Firmware components information',
operations=[
{'path': '/nodes/{node_ident}/firmware', 'method': 'GET'}
],
),
policy.DocumentedRuleDefault(
name='baremetal:node:vmedia:attach',
check_str=SYSTEM_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Attach a virtual media device to a node',
operations=[
{'path': '/nodes/{node_ident}/vmedia', 'method': 'POST'}\
],
),
policy.DocumentedRuleDefault(
name='baremetal:node:vmedia:detach',
check_str=SYSTEM_OR_PROJECT_MEMBER,
scope_types=['system', 'project'],
description='Detach a virtual media device from a node',
operations=[
{'path': '/nodes/{node_ident}/vmedia', 'method': 'DELETE'}
],
),
]
deprecated_port_reason = """
The baremetal port API is now aware of system scope and default roles.
"""
deprecated_port_get = policy.DeprecatedRule(
name='baremetal:port:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_port_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_port_list = policy.DeprecatedRule(
name='baremetal:port:list',
check_str='rule:baremetal:port:get',
deprecated_reason=deprecated_port_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_port_list_all = policy.DeprecatedRule(
name='baremetal:port:list_all',
check_str='rule:baremetal:port:get',
deprecated_reason=deprecated_port_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_port_create = policy.DeprecatedRule(
name='baremetal:port:create',
check_str='rule:is_admin',
deprecated_reason=deprecated_port_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_port_delete = policy.DeprecatedRule(
name='baremetal:port:delete',
check_str='rule:is_admin',
deprecated_reason=deprecated_port_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_port_update = policy.DeprecatedRule(
name='baremetal:port:update',
check_str='rule:is_admin',
deprecated_reason=deprecated_port_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
port_policies = [
policy.DocumentedRuleDefault(
name='baremetal:port:get',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Retrieve Port records',
operations=[
{'path': '/ports/{port_id}', 'method': 'GET'},
{'path': '/nodes/{node_ident}/ports', 'method': 'GET'},
{'path': '/nodes/{node_ident}/ports/detail', 'method': 'GET'},
{'path': '/portgroups/{portgroup_ident}/ports', 'method': 'GET'},
{'path': '/portgroups/{portgroup_ident}/ports/detail',
'method': 'GET'}
],
deprecated_rule=deprecated_port_get
),
policy.DocumentedRuleDefault(
name='baremetal:port:list',
check_str=API_READER,
scope_types=['system', 'project'],
description='Retrieve multiple Port records, filtered by owner',
operations=[
{'path': '/ports', 'method': 'GET'},
{'path': '/ports/detail', 'method': 'GET'}
],
deprecated_rule=deprecated_port_list
),
policy.DocumentedRuleDefault(
name='baremetal:port:list_all',
check_str=SYSTEM_READER,
scope_types=['system', 'project'],
description='Retrieve multiple Port records',
operations=[
{'path': '/ports', 'method': 'GET'},
{'path': '/ports/detail', 'method': 'GET'}
],
deprecated_rule=deprecated_port_list_all
),
policy.DocumentedRuleDefault(
name='baremetal:port:create',
check_str=SYSTEM_ADMIN_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Create Port records',
operations=[{'path': '/ports', 'method': 'POST'}],
deprecated_rule=deprecated_port_create
),
policy.DocumentedRuleDefault(
name='baremetal:port:delete',
check_str=SYSTEM_ADMIN_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Delete Port records',
operations=[{'path': '/ports/{port_id}', 'method': 'DELETE'}],
deprecated_rule=deprecated_port_delete
),
policy.DocumentedRuleDefault(
name='baremetal:port:update',
check_str=SYSTEM_MEMBER_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Update Port records',
operations=[{'path': '/ports/{port_id}', 'method': 'PATCH'}],
deprecated_rule=deprecated_port_update
),
]
deprecated_portgroup_reason = """
The baremetal port groups API is now aware of system scope and default roles.
"""
deprecated_portgroup_get = policy.DeprecatedRule(
name='baremetal:portgroup:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_portgroup_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_portgroup_create = policy.DeprecatedRule(
name='baremetal:portgroup:create',
check_str='rule:is_admin',
deprecated_reason=deprecated_portgroup_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_portgroup_delete = policy.DeprecatedRule(
name='baremetal:portgroup:delete',
check_str='rule:is_admin',
deprecated_reason=deprecated_portgroup_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_portgroup_update = policy.DeprecatedRule(
name='baremetal:portgroup:update',
check_str='rule:is_admin',
deprecated_reason=deprecated_portgroup_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
portgroup_policies = [
policy.DocumentedRuleDefault(
name='baremetal:portgroup:get',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Retrieve Portgroup records',
operations=[
{'path': '/portgroups', 'method': 'GET'},
{'path': '/portgroups/detail', 'method': 'GET'},
{'path': '/portgroups/{portgroup_ident}', 'method': 'GET'},
{'path': '/nodes/{node_ident}/portgroups', 'method': 'GET'},
{'path': '/nodes/{node_ident}/portgroups/detail', 'method': 'GET'},
],
deprecated_rule=deprecated_portgroup_get
),
policy.DocumentedRuleDefault(
name='baremetal:portgroup:create',
check_str=SYSTEM_ADMIN_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Create Portgroup records',
operations=[{'path': '/portgroups', 'method': 'POST'}],
deprecated_rule=deprecated_portgroup_create
),
policy.DocumentedRuleDefault(
name='baremetal:portgroup:delete',
check_str=SYSTEM_ADMIN_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Delete Portgroup records',
operations=[
{'path': '/portgroups/{portgroup_ident}', 'method': 'DELETE'}
],
deprecated_rule=deprecated_portgroup_delete
),
policy.DocumentedRuleDefault(
name='baremetal:portgroup:update',
check_str=SYSTEM_MEMBER_OR_OWNER_ADMIN,
scope_types=['system', 'project'],
description='Update Portgroup records',
operations=[
{'path': '/portgroups/{portgroup_ident}', 'method': 'PATCH'}
],
deprecated_rule=deprecated_portgroup_update
),
policy.DocumentedRuleDefault(
name='baremetal:portgroup:list',
check_str=API_READER,
scope_types=['system', 'project'],
description='Retrieve multiple Port records, filtered by owner',
operations=[
{'path': '/portgroups', 'method': 'GET'},
{'path': '/portgroups/detail', 'method': 'GET'}
],
deprecated_rule=deprecated_portgroup_get
),
policy.DocumentedRuleDefault(
name='baremetal:portgroup:list_all',
check_str=SYSTEM_READER,
scope_types=['system', 'project'],
description='Retrieve multiple Port records',
operations=[
{'path': '/portgroups', 'method': 'GET'},
{'path': '/portgroups/detail', 'method': 'GET'}
],
deprecated_rule=deprecated_portgroup_get
),
]
deprecated_chassis_reason = """
The baremetal chassis API is now aware of system scope and default roles.
"""
deprecated_chassis_get = policy.DeprecatedRule(
name='baremetal:chassis:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_chassis_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_chassis_create = policy.DeprecatedRule(
name='baremetal:chassis:create',
check_str='rule:is_admin',
deprecated_reason=deprecated_chassis_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_chassis_delete = policy.DeprecatedRule(
name='baremetal:chassis:delete',
check_str='rule:is_admin',
deprecated_reason=deprecated_chassis_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_chassis_update = policy.DeprecatedRule(
name='baremetal:chassis:update',
check_str='rule:is_admin',
deprecated_reason=deprecated_chassis_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
chassis_policies = [
policy.DocumentedRuleDefault(
name='baremetal:chassis:get',
check_str=SYSTEM_READER,
scope_types=['system'],
description='Retrieve Chassis records',
operations=[
{'path': '/chassis', 'method': 'GET'},
{'path': '/chassis/detail', 'method': 'GET'},
{'path': '/chassis/{chassis_id}', 'method': 'GET'}
],
deprecated_rule=deprecated_chassis_get
),
policy.DocumentedRuleDefault(
name='baremetal:chassis:create',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Create Chassis records',
operations=[{'path': '/chassis', 'method': 'POST'}],
deprecated_rule=deprecated_chassis_create
),
policy.DocumentedRuleDefault(
name='baremetal:chassis:delete',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Delete Chassis records',
operations=[{'path': '/chassis/{chassis_id}', 'method': 'DELETE'}],
deprecated_rule=deprecated_chassis_delete
),
policy.DocumentedRuleDefault(
name='baremetal:chassis:update',
check_str=SYSTEM_MEMBER,
scope_types=['system'],
description='Update Chassis records',
operations=[{'path': '/chassis/{chassis_id}', 'method': 'PATCH'}],
deprecated_rule=deprecated_chassis_update
),
]
deprecated_driver_reason = """
The baremetal driver API is now aware of system scope and default roles.
"""
deprecated_driver_get = policy.DeprecatedRule(
name='baremetal:driver:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_driver_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_driver_get_properties = policy.DeprecatedRule(
name='baremetal:driver:get_properties',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_driver_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_driver_get_raid_properties = policy.DeprecatedRule(
name='baremetal:driver:get_raid_logical_disk_properties',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_driver_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
driver_policies = [
policy.DocumentedRuleDefault(
name='baremetal:driver:get',
check_str=SYSTEM_READER,
scope_types=['system'],
description='View list of available drivers',
operations=[
{'path': '/drivers', 'method': 'GET'},
{'path': '/drivers/{driver_name}', 'method': 'GET'}
],
deprecated_rule=deprecated_driver_get
),
policy.DocumentedRuleDefault(
name='baremetal:driver:get_properties',
check_str=SYSTEM_READER,
scope_types=['system'],
description='View driver-specific properties',
operations=[
{'path': '/drivers/{driver_name}/properties', 'method': 'GET'}
],
deprecated_rule=deprecated_driver_get_properties
),
policy.DocumentedRuleDefault(
name='baremetal:driver:get_raid_logical_disk_properties',
check_str=SYSTEM_READER,
scope_types=['system'],
description='View driver-specific RAID metadata',
operations=[
{'path': '/drivers/{driver_name}/raid/logical_disk_properties',
'method': 'GET'}
],
deprecated_rule=deprecated_driver_get_raid_properties
),
]
deprecated_vendor_reason = """
The baremetal vendor passthru API is now aware of system scope and default
roles.
"""
deprecated_node_passthru = policy.DeprecatedRule(
name='baremetal:node:vendor_passthru',
check_str='rule:is_admin',
deprecated_reason=deprecated_vendor_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_driver_passthru = policy.DeprecatedRule(
name='baremetal:driver:vendor_passthru',
check_str='rule:is_admin',
deprecated_reason=deprecated_vendor_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
vendor_passthru_policies = [
policy.DocumentedRuleDefault(
name='baremetal:node:vendor_passthru',
check_str=SYSTEM_ADMIN,
# NOTE(TheJulia): Project scope listed, but not a project scoped role
# as some operators may find it useful to provide access to say owner
# admins.
scope_types=['system', 'project'],
description='Access vendor-specific Node functions',
operations=[
{'path': 'nodes/{node_ident}/vendor_passthru/methods',
'method': 'GET'},
{'path': 'nodes/{node_ident}/vendor_passthru?method={method_name}',
'method': 'GET'},
{'path': 'nodes/{node_ident}/vendor_passthru?method={method_name}',
'method': 'PUT'},
{'path': 'nodes/{node_ident}/vendor_passthru?method={method_name}',
'method': 'POST'},
{'path': 'nodes/{node_ident}/vendor_passthru?method={method_name}',
'method': 'PATCH'},
{'path': 'nodes/{node_ident}/vendor_passthru?method={method_name}',
'method': 'DELETE'},
],
deprecated_rule=deprecated_node_passthru
),
policy.DocumentedRuleDefault(
name='baremetal:driver:vendor_passthru',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Access vendor-specific Driver functions',
operations=[
{'path': 'drivers/{driver_name}/vendor_passthru/methods',
'method': 'GET'},
{'path': 'drivers/{driver_name}/vendor_passthru?'
'method={method_name}',
'method': 'GET'},
{'path': 'drivers/{driver_name}/vendor_passthru?'
'method={method_name}',
'method': 'PUT'},
{'path': 'drivers/{driver_name}/vendor_passthru?'
'method={method_name}',
'method': 'POST'},
{'path': 'drivers/{driver_name}/vendor_passthru?'
'method={method_name}',
'method': 'PATCH'},
{'path': 'drivers/{driver_name}/vendor_passthru?'
'method={method_name}',
'method': 'DELETE'}
],
deprecated_rule=deprecated_driver_passthru
),
]
deprecated_utility_reason = """
The baremetal utility API is now aware of system scope and default
roles.
"""
deprecated_ipa_heartbeat = policy.DeprecatedRule(
name='baremetal:node:ipa_heartbeat',
check_str='rule:public_api',
deprecated_reason=deprecated_utility_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_ipa_lookup = policy.DeprecatedRule(
name='baremetal:driver:ipa_lookup',
check_str='rule:public_api',
deprecated_reason=deprecated_utility_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
# NOTE(TheJulia): Empty check strings basically mean nothing to apply,
# and the request is permitted.
utility_policies = [
policy.DocumentedRuleDefault(
name='baremetal:node:ipa_heartbeat',
check_str='',
description='Receive heartbeats from IPA ramdisk',
operations=[{'path': '/heartbeat/{node_ident}', 'method': 'POST'}],
deprecated_rule=deprecated_ipa_heartbeat
),
policy.DocumentedRuleDefault(
name='baremetal:driver:ipa_lookup',
check_str='',
description='Access IPA ramdisk functions',
operations=[{'path': '/lookup', 'method': 'GET'}],
deprecated_rule=deprecated_ipa_lookup
),
policy.DocumentedRuleDefault(
name='baremetal:driver:ipa_continue_inspection',
check_str='',
description='Receive inspection data from the ramdisk',
operations=[{'path': '/continue_inspection', 'method': 'POST'}],
),
]
deprecated_volume_reason = """
The baremetal volume API is now aware of system scope and default
roles.
"""
deprecated_volume_get = policy.DeprecatedRule(
name='baremetal:volume:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_volume_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_volume_create = policy.DeprecatedRule(
name='baremetal:volume:create',
check_str='rule:is_admin',
deprecated_reason=deprecated_volume_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_volume_delete = policy.DeprecatedRule(
name='baremetal:volume:delete',
check_str='rule:is_admin',
deprecated_reason=deprecated_volume_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_volume_update = policy.DeprecatedRule(
name='baremetal:volume:update',
check_str='rule:is_admin',
deprecated_reason=deprecated_volume_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
volume_policies = [
policy.DocumentedRuleDefault(
name='baremetal:volume:list_all',
check_str=SYSTEM_READER,
scope_types=['system', 'project'],
description=('Retrieve a list of all Volume connector and target '
'records'),
operations=[
{'path': '/volume/connectors', 'method': 'GET'},
{'path': '/volume/targets', 'method': 'GET'},
{'path': '/nodes/{node_ident}/volume/connectors', 'method': 'GET'},
{'path': '/nodes/{node_ident}/volume/targets', 'method': 'GET'}
],
deprecated_rule=deprecated_volume_get
),
policy.DocumentedRuleDefault(
name='baremetal:volume:list',
check_str=API_READER,
scope_types=['system', 'project'],
description='Retrieve a list of Volume connector and target records',
operations=[
{'path': '/volume/connectors', 'method': 'GET'},
{'path': '/volume/targets', 'method': 'GET'},
{'path': '/nodes/{node_ident}/volume/connectors', 'method': 'GET'},
{'path': '/nodes/{node_ident}/volume/targets', 'method': 'GET'}
],
deprecated_rule=deprecated_volume_get
),
policy.DocumentedRuleDefault(
name='baremetal:volume:get',
check_str=SYSTEM_OR_PROJECT_READER,
scope_types=['system', 'project'],
description='Retrieve Volume connector and target records',
operations=[
{'path': '/volume', 'method': 'GET'},
{'path': '/volume/connectors', 'method': 'GET'},
{'path': '/volume/connectors/{volume_connector_id}',
'method': 'GET'},
{'path': '/volume/targets', 'method': 'GET'},
{'path': '/volume/targets/{volume_target_id}', 'method': 'GET'},
{'path': '/nodes/{node_ident}/volume', 'method': 'GET'},
{'path': '/nodes/{node_ident}/volume/connectors', 'method': 'GET'},
{'path': '/nodes/{node_ident}/volume/targets', 'method': 'GET'}
],
deprecated_rule=deprecated_volume_get
),
policy.DocumentedRuleDefault(
name='baremetal:volume:create',
check_str=SYSTEM_MEMBER_OR_OWNER_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Create Volume connector and target records',
operations=[
{'path': '/volume/connectors', 'method': 'POST'},
{'path': '/volume/targets', 'method': 'POST'}
],
deprecated_rule=deprecated_volume_create
),
policy.DocumentedRuleDefault(
name='baremetal:volume:delete',
check_str=SYSTEM_MEMBER_OR_OWNER_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Delete Volume connector and target records',
operations=[
{'path': '/volume/connectors/{volume_connector_id}',
'method': 'DELETE'},
{'path': '/volume/targets/{volume_target_id}',
'method': 'DELETE'}
],
deprecated_rule=deprecated_volume_delete
),
policy.DocumentedRuleDefault(
name='baremetal:volume:update',
check_str=SYSTEM_OR_OWNER_MEMBER_AND_LESSEE_ADMIN,
scope_types=['system', 'project'],
description='Update Volume connector and target records',
operations=[
{'path': '/volume/connectors/{volume_connector_id}',
'method': 'PATCH'},
{'path': '/volume/targets/{volume_target_id}',
'method': 'PATCH'}
],
deprecated_rule=deprecated_volume_update
),
policy.DocumentedRuleDefault(
name='baremetal:volume:view_target_properties',
check_str=TARGET_PROPERTIES_READER,
scope_types=['system', 'project'],
description='Ability to view volume target properties',
operations=[
{'path': '/volume/connectors/{volume_connector_id}',
'method': 'GET'},
{'path': '/volume/targets/{volume_target_id}',
'method': 'GET'}
],
deprecated_rule=deprecated_volume_update
),
]
deprecated_conductor_reason = """
The baremetal conductor API is now aware of system scope and default
roles.
"""
deprecated_conductor_get = policy.DeprecatedRule(
name='baremetal:conductor:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_conductor_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
conductor_policies = [
policy.DocumentedRuleDefault(
name='baremetal:conductor:get',
check_str=SYSTEM_READER,
scope_types=['system'],
description='Retrieve Conductor records',
operations=[
{'path': '/conductors', 'method': 'GET'},
{'path': '/conductors/{hostname}', 'method': 'GET'}
],
deprecated_rule=deprecated_conductor_get
),
]
deprecated_allocation_reason = """
The baremetal allocation API is now aware of system scope and default
roles.
"""
deprecated_allocation_get = policy.DeprecatedRule(
name='baremetal:allocation:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_allocation_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_allocation_list = policy.DeprecatedRule(
name='baremetal:allocation:list',
check_str='rule:baremetal:allocation:get',
deprecated_reason=deprecated_allocation_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_allocation_list_all = policy.DeprecatedRule(
name='baremetal:allocation:list_all',
check_str='rule:baremetal:allocation:get and is_admin_project:True',
deprecated_reason=deprecated_allocation_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_allocation_create = policy.DeprecatedRule(
name='baremetal:allocation:create',
check_str='rule:is_admin and is_admin_project:True',
deprecated_reason=deprecated_allocation_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_allocation_create_restricted = policy.DeprecatedRule(
name='baremetal:allocation:create_restricted',
check_str='rule:baremetal:allocation:create',
deprecated_reason=deprecated_allocation_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_allocation_delete = policy.DeprecatedRule(
name='baremetal:allocation:delete',
check_str='rule:is_admin',
deprecated_reason=deprecated_allocation_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_allocation_update = policy.DeprecatedRule(
name='baremetal:allocation:update',
check_str='rule:is_admin',
deprecated_reason=deprecated_allocation_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
allocation_policies = [
policy.DocumentedRuleDefault(
name='baremetal:allocation:get',
check_str=ALLOCATION_READER,
scope_types=['system', 'project'],
description='Retrieve Allocation records',
operations=[
{'path': '/allocations/{allocation_id}', 'method': 'GET'},
{'path': '/nodes/{node_ident}/allocation', 'method': 'GET'}
],
deprecated_rule=deprecated_allocation_get
),
policy.DocumentedRuleDefault(
name='baremetal:allocation:list',
check_str=API_READER,
scope_types=['system', 'project'],
description='Retrieve multiple Allocation records, filtered by owner',
operations=[{'path': '/allocations', 'method': 'GET'}],
deprecated_rule=deprecated_allocation_list
),
policy.DocumentedRuleDefault(
name='baremetal:allocation:list_all',
check_str=SYSTEM_READER,
scope_types=['system', 'project'],
description='Retrieve multiple Allocation records',
operations=[{'path': '/allocations', 'method': 'GET'}],
deprecated_rule=deprecated_allocation_list_all
),
policy.DocumentedRuleDefault(
name='baremetal:allocation:create',
check_str=ALLOCATION_CREATOR,
scope_types=['system', 'project'],
description='Create Allocation records',
operations=[{'path': '/allocations', 'method': 'POST'}],
deprecated_rule=deprecated_allocation_create
),
policy.DocumentedRuleDefault(
name='baremetal:allocation:create_restricted',
check_str=SYSTEM_MEMBER,
scope_types=['system', 'project'],
description=(
'Create Allocation records with a specific owner.'
),
operations=[{'path': '/allocations', 'method': 'POST'}],
deprecated_rule=deprecated_allocation_create_restricted
),
policy.DocumentedRuleDefault(
name='baremetal:allocation:delete',
check_str=ALLOCATION_MEMBER,
scope_types=['system', 'project'],
description='Delete Allocation records',
operations=[
{'path': '/allocations/{allocation_id}', 'method': 'DELETE'},
{'path': '/nodes/{node_ident}/allocation', 'method': 'DELETE'}],
deprecated_rule=deprecated_allocation_delete
),
policy.DocumentedRuleDefault(
name='baremetal:allocation:update',
check_str=ALLOCATION_MEMBER,
scope_types=['system', 'project'],
description='Change name and extra fields of an allocation',
operations=[
{'path': '/allocations/{allocation_id}', 'method': 'PATCH'},
],
deprecated_rule=deprecated_allocation_update
),
policy.DocumentedRuleDefault(
name='baremetal:allocation:create_pre_rbac',
# NOTE(TheJulia): First part of the check string is for classical
# administrative rights with someone using a baremetal project.
# The latter is more for projects and services using admin project
# rights. Specific checking because of the expanded rights of
# this functionality.
check_str=('(rule:is_member and role:baremetal_admin) or (is_admin_project:True and role:admin)'), # noqa
scope_types=['project'],
description=('Logical restrictor to prevent legacy allocation rule '
'missuse - Requires blank allocations to originate from '
'the legacy baremetal_admin.'),
operations=[
{'path': '/allocations/{allocation_id}', 'method': 'PATCH'},
],
deprecated_reason=deprecated_allocation_reason
),
]
deprecated_event_reason = """
The baremetal event API is now aware of system scope and default
roles.
"""
deprecated_event_create = policy.DeprecatedRule(
name='baremetal:events:post',
check_str='rule:is_admin',
deprecated_reason=deprecated_event_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
event_policies = [
policy.DocumentedRuleDefault(
name='baremetal:events:post',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Post events',
operations=[{'path': '/events', 'method': 'POST'}],
deprecated_rule=deprecated_event_create
)
]
deprecated_template_reason = """
The baremetal deploy template API is now aware of system scope and
default roles.
"""
deprecated_deploy_template_get = policy.DeprecatedRule(
name='baremetal:deploy_template:get',
check_str='rule:is_admin or rule:is_observer',
deprecated_reason=deprecated_template_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_deploy_template_create = policy.DeprecatedRule(
name='baremetal:deploy_template:create',
check_str='rule:is_admin',
deprecated_reason=deprecated_template_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_deploy_template_delete = policy.DeprecatedRule(
name='baremetal:deploy_template:delete',
check_str='rule:is_admin',
deprecated_reason=deprecated_template_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deprecated_deploy_template_update = policy.DeprecatedRule(
name='baremetal:deploy_template:update',
check_str='rule:is_admin',
deprecated_reason=deprecated_template_reason,
deprecated_since=versionutils.deprecated.WALLABY
)
deploy_template_policies = [
policy.DocumentedRuleDefault(
name='baremetal:deploy_template:get',
check_str=SYSTEM_READER,
scope_types=['system'],
description='Retrieve Deploy Template records',
operations=[
{'path': '/deploy_templates', 'method': 'GET'},
{'path': '/deploy_templates/{deploy_template_ident}',
'method': 'GET'}
],
deprecated_rule=deprecated_deploy_template_get
),
policy.DocumentedRuleDefault(
name='baremetal:deploy_template:create',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Create Deploy Template records',
operations=[{'path': '/deploy_templates', 'method': 'POST'}],
deprecated_rule=deprecated_deploy_template_create
),
policy.DocumentedRuleDefault(
name='baremetal:deploy_template:delete',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Delete Deploy Template records',
operations=[
{'path': '/deploy_templates/{deploy_template_ident}',
'method': 'DELETE'}
],
deprecated_rule=deprecated_deploy_template_delete
),
policy.DocumentedRuleDefault(
name='baremetal:deploy_template:update',
check_str=SYSTEM_ADMIN,
scope_types=['system'],
description='Update Deploy Template records',
operations=[
{'path': '/deploy_templates/{deploy_template_ident}',
'method': 'PATCH'}
],
deprecated_rule=deprecated_deploy_template_update
),
]
def list_policies():
policies = itertools.chain(
default_policies,
node_policies,
port_policies,
portgroup_policies,
chassis_policies,
driver_policies,
vendor_passthru_policies,
utility_policies,
volume_policies,
conductor_policies,
allocation_policies,
event_policies,
deploy_template_policies,
)
return policies
@lockutils.synchronized('policy_enforcer')
def init_enforcer(policy_file=None, rules=None,
default_rule=None, use_conf=True):
"""Synchronously initializes the policy enforcer
:param policy_file: Custom policy file to use, if none is specified,
`CONF.oslo_policy.policy_file` will be used.
:param rules: Default dictionary / Rules to use. It will be
considered just in the first instantiation.
:param default_rule: Default rule to use,
CONF.oslo_policy.policy_default_rule will
be used if none is specified.
:param use_conf: Whether to load rules from config file.
"""
global _ENFORCER
if _ENFORCER:
return
# NOTE(tenbrae): Register defaults for policy-in-code here so that they are
# loaded exactly once - when this module-global is initialized.
# Defining these in the relevant API modules won't work
# because API classes lack singletons and don't use globals.
_ENFORCER = policy.Enforcer(
CONF, policy_file=policy_file,
rules=rules,
default_rule=default_rule,
use_conf=use_conf)
# NOTE(melwitt): Explictly disable the warnings for policies
# changing their default check_str. During policy-defaults-refresh
# work, all the policy defaults have been changed and warning for
# each policy started filling the logs limit for various tool.
# Once we move to new defaults only world then we can enable these
# warning again.
# TODO(TheJulia): *When* we go to enable warnings to be indicated
# we need to update the notice in the logs to indicate *when* the
# support for older policies will be removed.
_ENFORCER.suppress_default_change_warnings = True
_ENFORCER.register_defaults(list_policies())
def get_enforcer():
"""Provides access to the single instance of Policy enforcer."""
if not _ENFORCER:
init_enforcer()
return _ENFORCER
def get_oslo_policy_enforcer():
# This method is for use by oslopolicy CLI scripts. Those scripts need the
# 'output-file' and 'namespace' options, but having those in sys.argv means
# loading the Ironic config options will fail as those are not expected to
# be present. So we pass in an arg list with those stripped out.
conf_args = []
# Start at 1 because cfg.CONF expects the equivalent of sys.argv[1:]
i = 1
while i < len(sys.argv):
if sys.argv[i].strip('-') in ['namespace', 'output-file']:
i += 2
continue
conf_args.append(sys.argv[i])
i += 1
cfg.CONF(conf_args, project='ironic')
return get_enforcer()
# NOTE(tenbrae): We can't call these methods from within decorators because the
# 'target' and 'creds' parameter must be fetched from the call time
# context-local pecan.request magic variable, but decorators are compiled
# at module-load time.
def authorize(rule, target, creds, *args, **kwargs):
"""A shortcut for policy.Enforcer.authorize()
Checks authorization of a rule against the target and credentials, and
raises an exception if the rule is not defined.
Always returns true if CONF.auth_strategy is not keystone.
"""
if CONF.auth_strategy != 'keystone':
return True
enforcer = get_enforcer()
try:
return enforcer.authorize(rule, target, creds, do_raise=True,
*args, **kwargs)
except policy.PolicyNotAuthorized as e:
LOG.error('Rejecting authorization: %(error)s',
{'error': e})
raise exception.HTTPForbidden(resource=rule)
def check(rule, target, creds, *args, **kwargs):
"""A shortcut for policy.Enforcer.enforce()
Checks authorization of a rule against the target and credentials
and returns True or False.
"""
enforcer = get_enforcer()
return enforcer.enforce(rule, target, creds, *args, **kwargs)
def check_policy(rule, target, creds, *args, **kwargs):
"""Configuration aware role policy check wrapper.
Checks authorization of a rule against the target and credentials
and returns True or False.
Always returns true if CONF.auth_strategy is not keystone.
"""
if CONF.auth_strategy != 'keystone':
return True
enforcer = get_enforcer()
return enforcer.enforce(rule, target, creds, *args, **kwargs)