Beispiel #1
0
def create_pending_actions_db():
    """Create database objects including a pending NetworkingAction.

    The first version of this function was used to create the dump
    'pending-networking-actions.sql'.
    """
    # At a minimum we need a project, node, nic, switch, port, and network:
    api.project_create('runway')
    api.node_register(
        'node-1',
        obm={
            'type': MOCK_OBM_TYPE,
            'user': '******',
            'host': 'host',
            'password': '******',
        },
    )
    api.node_register_nic('node-1', 'pxe', 'de:ad:be:ef:20:16')
    api.switch_register('sw0',
                        type=MOCK_SWITCH_TYPE,
                        username='******',
                        hostname='host',
                        password='******',
                        )
    api.switch_register_port('sw0', 'gi1/0/4')
    api.port_connect_nic('sw0', 'gi1/0/4', 'node-1', 'pxe')
    api.project_connect_node('runway', 'node-1')
    api.network_create('runway_pxe', 'runway', 'runway', '')

    # Queue up a networking action. Importantly, we do *not* call
    # deferred.apply_networking, as that would flush the action and
    # remove it from the database.
    api.node_connect_network('node-1', 'pxe', 'runway_pxe')
Beispiel #2
0
def create_pending_actions_db():
    """Create database objects including a pending NetworkingAction.

    The first version of this function was used to create the dump
    'pending-networking-actions.sql'.
    """
    # At a minimum we need a project, node, nic, switch, port, and network:
    api.project_create('runway')
    api.node_register(
        'node-1',
        obm={
            'type': MOCK_OBM_TYPE,
            'user': '******',
            'host': 'host',
            'password': '******',
        },
    )
    api.node_register_nic('node-1', 'pxe', 'de:ad:be:ef:20:16')
    api.switch_register(
        'sw0',
        type=MOCK_SWITCH_TYPE,
        username='******',
        hostname='host',
        password='******',
    )
    api.switch_register_port('sw0', 'gi1/0/4')
    api.port_connect_nic('sw0', 'gi1/0/4', 'node-1', 'pxe')
    api.project_connect_node('runway', 'node-1')
    api.network_create('runway_pxe', 'runway', 'runway', '')

    # Queue up a networking action. Importantly, we do *not* call
    # deferred.apply_networking, as that would flush the action and
    # remove it from the database.
    api.node_connect_network('node-1', 'pxe', 'runway_pxe')
Beispiel #3
0
def network_create_simple(network, project):
    """Create a simple project-owned network.

    This is a shorthand for the network_create API call, that defaults
    parameters to the most common case---namely, that the network is owned by
    a project, has access only by that project, and uses an allocated
    underlying net_id.  Note that this is the only valid set of parameters for
    a network that belongs to a project.

    The test-suite uses this extensively, for tests that don't care about more
    complicated features of networks.
    """
    api.network_create(network, project, project, "")
Beispiel #4
0
def network_create_simple(network, project):
    """Create a simple project-owned network.

    This is a shorthand for the network_create API call, that defaults
    parameters to the most common case---namely, that the network is owned by
    a project, has access only by that project, and uses an allocated
    underlying net_id.  Note that this is the only valid set of parameters for
    a network that belongs to a project.

    The test-suite uses this extensively, for tests that don't care about more
    complicated features of networks.
    """
    api.network_create(network, project, project, "")
Beispiel #5
0
    def test_create_network_with_id_outside_pool(self):

        # create an admin owned network
        api.network_create('hammernet', 'admin', '', 1511)

        # administrators should be able to make different networks with the
        # same network id

        api.network_create('starfish', 'admin', '', 1511)
        network = api._must_find(model.Network, 'starfish')
        net_id = int(network.network_id)
        assert network.allocated is False
        assert net_id == 1511
Beispiel #6
0
    def test_create_network_with_id_outside_pool(self):
        """Test creation of networks whose ID is not in the pool."""

        # create an admin owned network
        api.network_create('hammernet', 'admin', '', 1511)

        # administrators should be able to make different networks with the
        # same network id

        api.network_create('starfish', 'admin', '', 1511)
        network = api.get_or_404(model.Network, 'starfish')
        net_id = int(network.network_id)
        assert network.allocated is False
        assert net_id == 1511
Beispiel #7
0
def test_vlanid_for_admin_network():
    """
    Test for valid vlanID for administrator-owned networks.
    """
    # create a network with a string vlan id
    with pytest.raises(errors.BadArgumentError):
        api.network_create('hammernet', 'admin', '', 'yes')

    # create a network with a vlanid>4096
    with pytest.raises(errors.BadArgumentError):
        api.network_create('nailnet', 'admin', '', '5023')

    # create a netowrk with a vlanid<1
    with pytest.raises(errors.BadArgumentError):
        api.network_create('nailnet', 'admin', '', '-2')
Beispiel #8
0
def test_vlanid_for_admin_network():
    """
    Test for valid vlanID for administrator-owned networks.
    """
    # create a network with a string vlan id
    with pytest.raises(errors.BadArgumentError):
        api.network_create('hammernet', 'admin', '', 'yes')

    # create a network with a vlanid>4096
    with pytest.raises(errors.BadArgumentError):
        api.network_create('nailnet', 'admin', '', '5023')

    # create a netowrk with a vlanid<1
    with pytest.raises(errors.BadArgumentError):
        api.network_create('nailnet', 'admin', '', '-2')
Beispiel #9
0
def test_apply_networking(switch, network, fresh_database):
    '''Test to validate apply_networking commits actions incrementally

    This test verifies that the apply_networking() function in hil/deferred.py
    incrementally commits actions, which ensures that any error on an action
    will not require a complete rerun of the prior actions (e.g. if an error
    is thrown on the 3rd action, the 1st and 2nd action will have already been
    committed)

    The test also verifies that if a new networking action fails, then the
    old networking actions in the queue were commited.
    '''
    nic = []
    actions = []
    # initialize 3 nics and networking actions
    for i in range(0, 2):
        interface = 'gi1/0/%d' % (i)
        nic.append(new_nic(str(i)))
        nic[i].port = model.Port(label=interface, switch=switch)
        unique_id = str(uuid.uuid4())
        actions.append(
            model.NetworkingAction(nic=nic[i],
                                   new_network=network,
                                   channel='vlan/native',
                                   type='modify_port',
                                   uuid=unique_id,
                                   status='PENDING'))

    # Create another aciton of type revert_port. This action is invalid for the
    # test switch because the switch raises an error when the networking action
    # is of type revert port.
    unique_id = str(uuid.uuid4())
    nic.append(new_nic('2'))
    nic[2].port = model.Port(label=interface, switch=switch)
    actions.append(
        model.NetworkingAction(nic=nic[2],
                               new_network=None,
                               uuid=unique_id,
                               channel='',
                               status='PENDING',
                               type='revert_port'))

    # get some nic attributes before we close this db session.
    nic2_label = nic[2].label
    nic2_node = nic[2].owner.label

    for action in actions:
        db.session.add(action)
    db.session.commit()

    # simple check to ensure that right number of actions are added.
    total_count = db.session.query(model.NetworkingAction).count()
    assert total_count == 3

    deferred.apply_networking()

    # close the session opened by `apply_networking` when `handle_actions`
    # fails; without this the tests would just stall (when using postgres)
    db.session.close()

    local_db = new_db()

    errored_action = local_db.session \
        .query(model.NetworkingAction) \
        .order_by(model.NetworkingAction.id).filter_by(status='ERROR') \
        .one_or_none()

    # Count the number of actions with different statuses
    error_count = local_db.session \
        .query(model.NetworkingAction).filter_by(status='ERROR').count()

    pending_count = local_db.session \
        .query(model.NetworkingAction).filter_by(status='PENDING').count()

    done_count = local_db.session \
        .query(model.NetworkingAction).filter_by(status='DONE').count()

    # test that there's only 1 action that errored out in the queue and that it
    # is of type revert_port
    assert error_count == 1
    assert errored_action.type == 'revert_port'

    assert pending_count == 0
    assert done_count == 2
    local_db.session.commit()
    local_db.session.close()

    # add another action on a nic with a previously failed action.
    api.network_create('corsair', 'admin', '', '105')
    api.node_connect_network(nic2_node, nic2_label, 'corsair')

    # the api call should delete the errored action on that nic, and a new
    # pending action should appear.
    local_db = new_db()
    errored_action = local_db.session \
        .query(model.NetworkingAction) \
        .order_by(model.NetworkingAction.id).filter_by(status='ERROR') \
        .one_or_none()

    pending_action = local_db.session \
        .query(model.NetworkingAction) \
        .order_by(model.NetworkingAction.id).filter_by(status='PENDING') \
        .one_or_none()

    assert errored_action is None
    assert pending_action is not None

    local_db.session.commit()
    local_db.session.close()
Beispiel #10
0
    def test_create_network_with_id_from_pool(self):
        """Test creation of networks with IDs from the pool."""

        api.project_create('nuggets')

        # create a project owned network and get its network_id
        api.network_create('hammernet', 'nuggets', 'nuggets', '')
        network = api._must_find(model.Network, 'hammernet')
        net_id = int(network.network_id)
        assert network.allocated is True

        # create an admin owned network with net_id from pool
        api.network_create('nailnet', 'admin', '', 103)
        network = api._must_find(model.Network, 'nailnet')
        assert network.allocated is True

        # creating a network with the same network id should raise an error
        with pytest.raises(errors.BlockedError):
            api.network_create('redbone', 'admin', '', 103)
        with pytest.raises(errors.BlockedError):
            api.network_create('starfish', 'admin', '', net_id)

        # free the network ids by deleting the networks
        api.network_delete('hammernet')
        api.network_delete('nailnet')
        api._assert_absent(model.Network, 'hammernet')
        api._assert_absent(model.Network, 'nailnet')

        # after deletion we should be able to create admin networks with those
        # network_ids
        api.network_create('redbone', 'admin', '', 103)
        network = api._must_find(model.Network, 'redbone')
        assert int(network.network_id) == 103

        api.network_create('starfish', 'admin', '', net_id)
        network = api._must_find(model.Network, 'starfish')
        assert int(network.network_id) == net_id
Beispiel #11
0
def test_apply_networking(switch, network, fresh_database):
    '''Test to validate apply_networking commits actions incrementally

    This test verifies that the apply_networking() function in hil/deferred.py
    incrementally commits actions, which ensures that any error on an action
    will not require a complete rerun of the prior actions (e.g. if an error
    is thrown on the 3rd action, the 1st and 2nd action will have already been
    committed)

    The test also verifies that if a new networking action fails, then the
    old networking actions in the queue were commited.
    '''
    nic = []
    actions = []
    # initialize 3 nics and networking actions
    for i in range(0, 2):
        interface = 'gi1/0/%d' % (i)
        nic.append(new_nic(str(i)))
        nic[i].port = model.Port(label=interface, switch=switch)
        unique_id = str(uuid.uuid4())
        actions.append(model.NetworkingAction(nic=nic[i],
                                              new_network=network,
                                              channel='vlan/native',
                                              type='modify_port',
                                              uuid=unique_id,
                                              status='PENDING'))

    # Create another aciton of type revert_port. This action is invalid for the
    # test switch because the switch raises an error when the networking action
    # is of type revert port.
    unique_id = str(uuid.uuid4())
    nic.append(new_nic('2'))
    nic[2].port = model.Port(label=interface, switch=switch)
    actions.append(model.NetworkingAction(nic=nic[2],
                                          new_network=None,
                                          uuid=unique_id,
                                          channel='',
                                          status='PENDING',
                                          type='revert_port'))

    # get some nic attributes before we close this db session.
    nic2_label = nic[2].label
    nic2_node = nic[2].owner.label

    for action in actions:
        db.session.add(action)
    db.session.commit()

    # simple check to ensure that right number of actions are added.
    total_count = db.session.query(model.NetworkingAction).count()
    assert total_count == 3

    deferred.apply_networking()

    # close the session opened by `apply_networking` when `handle_actions`
    # fails; without this the tests would just stall (when using postgres)
    db.session.close()

    local_db = new_db()

    errored_action = local_db.session \
        .query(model.NetworkingAction) \
        .order_by(model.NetworkingAction.id).filter_by(status='ERROR') \
        .one_or_none()

    # Count the number of actions with different statuses
    error_count = local_db.session \
        .query(model.NetworkingAction).filter_by(status='ERROR').count()

    pending_count = local_db.session \
        .query(model.NetworkingAction).filter_by(status='PENDING').count()

    done_count = local_db.session \
        .query(model.NetworkingAction).filter_by(status='DONE').count()

    # test that there's only 1 action that errored out in the queue and that it
    # is of type revert_port
    assert error_count == 1
    assert errored_action.type == 'revert_port'

    assert pending_count == 0
    assert done_count == 2
    local_db.session.commit()
    local_db.session.close()

    # add another action on a nic with a previously failed action.
    api.network_create('corsair', 'admin', '', '105')
    api.node_connect_network(nic2_node, nic2_label, 'corsair')

    # the api call should delete the errored action on that nic, and a new
    # pending action should appear.
    local_db = new_db()
    errored_action = local_db.session \
        .query(model.NetworkingAction) \
        .order_by(model.NetworkingAction.id).filter_by(status='ERROR') \
        .one_or_none()

    pending_action = local_db.session \
        .query(model.NetworkingAction) \
        .order_by(model.NetworkingAction.id).filter_by(status='PENDING') \
        .one_or_none()

    assert errored_action is None
    assert pending_action is not None

    local_db.session.commit()
    local_db.session.close()
Beispiel #12
0
    def test_create_network_with_id_from_pool(self):
        """Test creation of networks with IDs from the pool."""

        api.project_create('nuggets')

        # create a project owned network and get its network_id
        api.network_create('hammernet', 'nuggets', 'nuggets', '')
        network = api.get_or_404(model.Network, 'hammernet')
        net_id = int(network.network_id)
        assert network.allocated is True

        # create an admin owned network with net_id from pool
        api.network_create('nailnet', 'admin', '', 103)
        network = api.get_or_404(model.Network, 'nailnet')
        assert network.allocated is True

        # creating a network with the same network id should raise an error
        with pytest.raises(errors.BlockedError):
            api.network_create('redbone', 'admin', '', 103)
        with pytest.raises(errors.BlockedError):
            api.network_create('starfish', 'admin', '', net_id)

        # free the network ids by deleting the networks
        api.network_delete('hammernet')
        api.network_delete('nailnet')
        api.absent_or_conflict(model.Network, 'hammernet')
        api.absent_or_conflict(model.Network, 'nailnet')

        # after deletion we should be able to create admin networks with those
        # network_ids
        api.network_create('redbone', 'admin', '', 103)
        network = api.get_or_404(model.Network, 'redbone')
        assert int(network.network_id) == 103

        api.network_create('starfish', 'admin', '', net_id)
        network = api.get_or_404(model.Network, 'starfish')
        assert int(network.network_id) == net_id