def headnode_connect_network(headnode, hnic, network): """Connect a headnode's hnic to a network. Raises IllegalStateError if the headnode has already been started. Raises ProjectMismatchError if the project does not have access rights to the given network. Raises BadArgumentError if the network is a non-allocated network. This is currently unsupported due to an implementation limitation, but will be supported in a future release. See issue #333. """ headnode = get_or_404(model.Headnode, headnode) get_auth_backend().require_project_access(headnode.project) hnic = get_child_or_404(headnode, model.Hnic, hnic) network = get_or_404(model.Network, network) if not network.allocated: raise errors.BadArgumentError( "Headnodes may only be connected to networks " "allocated by the project.") if not headnode.dirty: raise errors.IllegalStateError project = headnode.project if (network.access) and (project not in network.access): raise errors.ProjectMismatchError( "Project does not have access to given network.") hnic.network = network db.session.commit()
def node_detach_network(node, nic, network): """Detach network ``network`` from physical nic ``nic``. Raises ProjectMismatchError if the node is not in a project. Raises BlockedError if there is already a pending network action. Raises BadArgumentError if the network is not attached to the nic. """ auth_backend = get_auth_backend() node = _must_find(model.Node, node) network = _must_find(model.Network, network) nic = _must_find_n(node, model.Nic, nic) if not node.project: raise errors.ProjectMismatchError("Node not in project") auth_backend.require_project_access(node.project) if nic.current_action: raise errors.BlockedError( "A networking operation is already active on the nic.") attachment = model.NetworkAttachment.query \ .filter_by(nic=nic, network=network).first() if attachment is None: raise errors.BadArgumentError( "The network is not attached to the nic.") db.session.add( model.NetworkingAction(type='modify_port', nic=nic, channel=attachment.channel, new_network=None)) db.session.commit() return '', 202
def node_detach_network(node, nic, network): """Detach network ``network`` from physical nic ``nic``. Raises ProjectMismatchError if the node is not in a project. Raises BlockedError if there is already a pending network action. Raises BadArgumentError if the network is not attached to the nic. """ auth_backend = get_auth_backend() node = get_or_404(model.Node, node) network = get_or_404(model.Network, network) nic = get_child_or_404(node, model.Nic, nic) if not node.project: raise errors.ProjectMismatchError("Node not in project") auth_backend.require_project_access(node.project) check_pending_action(nic) attachment = model.NetworkAttachment.query \ .filter_by(nic=nic, network=network).one_or_none() if attachment is None: raise errors.BadArgumentError( "The network is not attached to the nic.") switch = nic.port.owner switch.ensure_legal_operation(nic, 'detach', attachment.channel) unique_id = str(uuid.uuid4()) db.session.add( model.NetworkingAction(type='modify_port', nic=nic, channel=attachment.channel, uuid=unique_id, status='PENDING', new_network=None)) db.session.commit() return json.dumps({'status_id': unique_id}), 202
def node_connect_network(node, nic, network, channel=None): """Connect a physical NIC to a network, on channel. If channel is ``None``, use the allocator default. Raises ProjectMismatchError if the node is not in a project, or if the project does not have access rights to the given network. Raises BlockedError if there is a pending network action, or if the network is already attached to the nic, or if the channel is in use. Raises BadArgumentError if the channel is invalid for the network. """ def _have_attachment(nic, query): """Return whether there are any attachments matching ``query`` for ``nic``. ``query`` should an argument suitable to pass to db.query(...).filter """ return model.NetworkAttachment.query.filter( model.NetworkAttachment.nic == nic, query, ).first() is not None auth_backend = get_auth_backend() node = get_or_404(model.Node, node) nic = get_child_or_404(node, model.Nic, nic) network = get_or_404(model.Network, network) if not node.project: raise errors.ProjectMismatchError("Node not in project") auth_backend.require_project_access(node.project) project = node.project allocator = get_network_allocator() if nic.port is None: raise errors.NotFoundError("No port is connected to given nic.") check_pending_action(nic) if (network.access) and (project not in network.access): raise errors.ProjectMismatchError( "Project does not have access to given network.") if _have_attachment(nic, model.NetworkAttachment.network == network): raise errors.BlockedError( "The network is already attached to the nic.") if channel is None: channel = allocator.get_default_channel() if _have_attachment(nic, model.NetworkAttachment.channel == channel): raise errors.BlockedError("The channel is already in use on the nic.") if not allocator.is_legal_channel_for(channel, network.network_id): raise errors.BadArgumentError( "Channel %r, is not legal for this network." % channel) switch = nic.port.owner switch.ensure_legal_operation(nic, 'connect', channel) unique_id = str(uuid.uuid4()) db.session.add( model.NetworkingAction(type='modify_port', nic=nic, new_network=network, channel=channel, uuid=unique_id, status='PENDING')) db.session.commit() return json.dumps({'status_id': unique_id}), 202
def node_connect_network(node, nic, network, channel=None): """Connect a physical NIC to a network, on channel. If channel is ``None``, use the allocator default. Raises ProjectMismatchError if the node is not in a project, or if the project does not have access rights to the given network. Raises BlockedError if there is a pending network action, or if the network is already attached to the nic, or if the channel is in use. Raises BadArgumentError if the channel is invalid for the network. """ def _have_attachment(nic, query): """Return whether there are any attachments matching ``query`` for ``nic``. ``query`` should an argument suitable to pass to db.query(...).filter """ return model.NetworkAttachment.query.filter( model.NetworkAttachment.nic == nic, query, ).count() != 0 auth_backend = get_auth_backend() node = _must_find(model.Node, node) nic = _must_find_n(node, model.Nic, nic) network = _must_find(model.Network, network) if not node.project: raise errors.ProjectMismatchError("Node not in project") auth_backend.require_project_access(node.project) project = node.project allocator = get_network_allocator() if nic.port is None: raise errors.NotFoundError("No port is connected to given nic.") if nic.current_action: raise errors.BlockedError( "A networking operation is already active on the nic.") if (network.access) and (project not in network.access): raise errors.ProjectMismatchError( "Project does not have access to given network.") if _have_attachment(nic, model.NetworkAttachment.network == network): raise errors.BlockedError( "The network is already attached to the nic.") if channel is None: channel = allocator.get_default_channel() if _have_attachment(nic, model.NetworkAttachment.channel == channel): raise errors.BlockedError("The channel is already in use on the nic.") if not allocator.is_legal_channel_for(channel, network.network_id): raise errors.BadArgumentError( "Channel %r, is not legal for this network." % channel) db.session.add( model.NetworkingAction(type='modify_port', nic=nic, new_network=network, channel=channel)) db.session.commit() return '', 202