summaryrefslogtreecommitdiff
path: root/ironic/api/controllers/v1/utils.py
diff options
context:
space:
mode:
authorTzu-Mainn Chen <tzumainn@redhat.com>2019-11-19 00:08:54 +0000
committerTzu-Mainn Chen <tzumainn@redhat.com>2020-01-02 15:12:43 +0000
commit6f16a2268ce9c7e17c09a3ebd5f48c544e93c808 (patch)
tree5efd12ffda6abdb91a323ef1cc259e32ee993879 /ironic/api/controllers/v1/utils.py
parent2a43e371f17e78ea749bb0d17c98df24652aeb0c (diff)
downloadironic-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.py46
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.