diff options
author | Tzu-Mainn Chen <tzumainn@redhat.com> | 2019-11-19 00:08:54 +0000 |
---|---|---|
committer | Tzu-Mainn Chen <tzumainn@redhat.com> | 2020-01-02 15:12:43 +0000 |
commit | 6f16a2268ce9c7e17c09a3ebd5f48c544e93c808 (patch) | |
tree | 5efd12ffda6abdb91a323ef1cc259e32ee993879 /ironic/api/controllers/v1/utils.py | |
parent | 2a43e371f17e78ea749bb0d17c98df24652aeb0c (diff) | |
download | ironic-6f16a2268ce9c7e17c09a3ebd5f48c544e93c808.tar.gz |
Allow node owners to administer associated ports
Expose a port's node's owner to policy, giving Ironic admins
the option of modifying the policy file to allow users
specified by a node's owner field to perform API actions on
that node's associated ports.
Change-Id: I47ecbad9729f18dacc703e2a625ef3e92bfb00ed
Story: #2006506
Task: #37539
Diffstat (limited to 'ironic/api/controllers/v1/utils.py')
-rw-r--r-- | ironic/api/controllers/v1/utils.py | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/ironic/api/controllers/v1/utils.py b/ironic/api/controllers/v1/utils.py index fc6d00a9d..7989c8440 100644 --- a/ironic/api/controllers/v1/utils.py +++ b/ironic/api/controllers/v1/utils.py @@ -1228,6 +1228,52 @@ def check_node_list_policy(owner=None): return owner +def check_port_policy_and_retrieve(policy_name, port_uuid): + """Check if the specified policy authorizes this request on a port. + + :param: policy_name: Name of the policy to check. + :param: port_uuid: the UUID of a port. + + :raises: HTTPForbidden if the policy forbids access. + :raises: NodeNotFound if the node is not found. + :return: RPC port identified by port_uuid and associated node + """ + context = api.request.context + cdict = context.to_policy_values() + + try: + rpc_port = objects.Port.get_by_uuid(context, port_uuid) + except exception.PortNotFound: + # don't expose non-existence of port unless requester + # has generic access to policy + policy.authorize(policy_name, cdict, cdict) + raise + + rpc_node = objects.Node.get_by_id(context, rpc_port.node_id) + target_dict = dict(cdict) + target_dict['node.owner'] = rpc_node['owner'] + policy.authorize(policy_name, target_dict, cdict) + + return rpc_port, rpc_node + + +def check_port_list_policy(): + """Check if the specified policy authorizes this request on a port. + + :raises: HTTPForbidden if the policy forbids access. + :return: owner that should be used for list query, if needed + """ + cdict = api.request.context.to_policy_values() + try: + policy.authorize('baremetal:port:list_all', cdict, cdict) + except exception.HTTPForbidden: + owner = cdict.get('project_id') + if not owner: + raise + policy.authorize('baremetal:port:list', cdict, cdict) + return owner + + def allow_build_configdrive(): """Check if building configdrive is allowed. |