Exemple #1
0
def node_register(node, **kwargs):
    """Create node.

    If the node already exists, a DuplicateError will be raised.
    The node is initially registered with no nics; see the method
    node_register_nic.
    """
    get_auth_backend().require_admin()
    absent_or_conflict(model.Node, node)
    obm_type = kwargs['obm']['type']
    cls = concrete_class_for(model.Obm, obm_type)
    if cls is None:
        raise errors.BadArgumentError('%r is not a valid OBM type.' % obm_type)
    cls.validate(kwargs['obm'])
    node_obj = model.Node(label=node, obm=cls(**kwargs['obm']))
    if 'metadata' in kwargs:
        for label, value in kwargs['metadata'].items():
            metadata_obj = model.Metadata(label, json.dumps(value), node_obj)
            db.session.add(metadata_obj)
    db.session.add(node_obj)
    db.session.commit()
Exemple #2
0
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
Exemple #3
0
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).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)

    db.session.add(
        model.NetworkingAction(type='modify_port',
                               nic=nic,
                               channel=attachment.channel,
                               new_network=None))
    db.session.commit()
    return '', 202
Exemple #4
0
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
Exemple #5
0
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