def show_network(network): """Show details of a network. Returns a JSON object representing a network. See `docs/rest_api.md` for a full description of the output. """ allocator = get_network_allocator() auth_backend = get_auth_backend() network = _must_find(model.Network, network) if network.access: authorized = False for proj in network.access: authorized = authorized or auth_backend.have_project_access(proj) if not authorized: raise errors.AuthorizationError( "You do not have access to this network.") result = { 'name': network.label, 'channels': allocator.legal_channels_for(network.network_id), } if network.owner is None: result['owner'] = 'admin' else: result['owner'] = network.owner.label if network.access: result['access'] = [p.label for p in network.access] else: result['access'] = None return json.dumps(result, sort_keys=True)
def list_network_attachments(network, project=None): """Lists all the attachments from <project> for <network> If <project> is `None`, lists all attachments for <network> """ auth_backend = get_auth_backend() network = _must_find(model.Network, network) # Determine if caller has access to owning project if network.owner is None: owner_access = auth_backend.have_admin() else: owner_access = auth_backend.have_project_access(network.owner) if project is None: # No project means list all connected nodes # Only access to the project that owns the network or an admin can do # this if not owner_access: raise errors.AuthorizationError( "Operation requires admin rights or access to network's " "owning project") else: # Only list the nodes coming from the specified project that are # connected to this network. project = _must_find(model.Project, project) if not owner_access: # Caller does not own the network, so they need both basic access # to the network, and access to tueh queried project. if not (project in network.access and auth_backend.have_project_access(project)): raise errors.AuthorizationError( "You do not have access to this project.") attachments = network.attachments nodes = {} for attachment in attachments: if project is None or project is attachment.nic.owner.project: node = { 'nic': attachment.nic.label, 'channel': attachment.channel, 'project': attachment.nic.owner.project.label } nodes[attachment.nic.owner.label] = node return json.dumps(nodes, sort_keys=True)
def show_network(network): """Show details of a network. Returns a JSON object representing a network. See `docs/rest_api.md` for a full description of the output. """ allocator = get_network_allocator() auth_backend = get_auth_backend() network = get_or_404(model.Network, network) if network.access: authorized = False for proj in network.access: authorized = authorized or auth_backend.have_project_access(proj) if not authorized: raise errors.AuthorizationError( "You do not have access to this network.") result = { 'name': network.label, 'channels': allocator.legal_channels_for(network.network_id), } if network.owner is None: result['owner'] = 'admin' else: result['owner'] = network.owner.label if network.access: result['access'] = [p.label for p in network.access] else: result['access'] = None connected_nodes = {} for n in network.attachments: if auth_backend.have_project_access(network.owner) or \ auth_backend.have_project_access(n.nic.owner.project): node, nic = n.nic.owner.label, n.nic.label # build a dictonary mapping a node to list of nics if node not in connected_nodes: connected_nodes[node] = [nic] else: connected_nodes[node].append(nic) result['connected-nodes'] = connected_nodes return json.dumps(result, sort_keys=True)
def network_revoke_project_access(project, network): """Remove access to <network> from <project>. If the project or network does not exist, a NotFoundError will be raised. If the project is the owner of the network a BlockedError will be raised. """ auth_backend = get_auth_backend() network = get_or_404(model.Network, network) project = get_or_404(model.Project, project) # must be admin, the owner of the network, or <project> to remove # <project>. if network.access: if not (auth_backend.have_admin() or (network.owner is not None and auth_backend.have_project_access(network.owner)) or (project in network.access and auth_backend.have_project_access(project))): raise errors.AuthorizationError( "You are not authorized to remove the " "specified project from this network.") if project not in network.access: raise errors.NotFoundError( "Network %r is not in project %r" % (network.label, project.label)) if project is network.owner: raise errors.BlockedError( "Project %r is owner of network %r and " "its access cannot be removed" % (project.label, network.label)) # TODO: Make this and the next loop more SQLAlchemy-friendly for attachment in network.attachments: if attachment.nic.owner.project.label == project.label: raise errors.BlockedError( "Project still has node(s) attached to the network") for hnic in network.hnics: if hnic.owner.project.label == project.label: raise errors.BlockedError( "Project still has headnode(s) attached to the network") network.access.remove(project) db.session.commit()