示例#1
0
def test_context_manager(context):

    ifname = context.new_ifname
    address = '00:11:22:36:47:58'
    spec = {'ifname': ifname, 'kind': 'dummy'}

    ifobj = context.ndb.interfaces.create(**spec)

    with ifobj:
        pass

    assert interface_exists(context.netns, ifname=ifname, state='down')

    with ifobj:
        ifobj['state'] = 'up'
        ifobj['address'] = address

    assert interface_exists(context.netns,
                            ifname=ifname,
                            address=address,
                            state='up')

    with ifobj:
        ifobj.remove()

    assert not interface_exists(context.netns, ifname=ifname)
def test_create(context):
    ifname = context.new_ifname
    iface = (context.ndb.interfaces.create(ifname=ifname,
                                           kind='dummy').commit())
    assert interface_exists(context.netns, ifname=ifname)
    iface.rollback()
    assert not interface_exists(context.netns, ifname=ifname)
示例#3
0
def _test_tunnel_endpoints(context, state):
    ifname = context.new_ifname
    ipaddr_local1 = context.new_ipaddr
    ipaddr_local2 = context.new_ipaddr
    ipaddr_remote = context.new_ipaddr
    kind = context.kind

    (context.ndb.interfaces.create(
        **{
            'ifname': ifname,
            'state': state,
            'kind': kind,
            f'{kind}_local': ipaddr_local1,
            f'{kind}_remote': ipaddr_remote,
        }).commit())

    def match(ifname, ipaddr):
        return (lambda x: x.get_nested('IFLA_LINKINFO', 'IFLA_INFO_KIND') ==
                kind and x.get_attr('IFLA_IFNAME') == ifname and x.get_nested(
                    'IFLA_LINKINFO',
                    'IFLA_INFO_DATA',
                    'IFLA_%s_LOCAL' % kind.upper(),
                ) == ipaddr)

    assert interface_exists(context.netns, match(ifname, ipaddr_local1))

    (context.ndb.interfaces[ifname].set(f'{kind}_local',
                                        ipaddr_local2).commit())

    assert interface_exists(context.netns, match(ifname, ipaddr_local2))
示例#4
0
def test_set(context):
    ifname = context.new_ifname
    (context
     .ndb
     .interfaces
     .create(ifname=ifname, kind='dummy', address='00:11:22:33:44:55')
     .commit())
    assert interface_exists(context.netns,
                            ifname=ifname,
                            address='00:11:22:33:44:55')
    (context
     .ndb
     .interfaces[ifname]
     .set('address', '00:11:22:aa:aa:aa')
     .commit())
    assert not interface_exists(context.netns,
                                ifname=ifname,
                                address='00:11:22:33:44:55')
    assert interface_exists(context.netns,
                            ifname=ifname,
                            address='00:11:22:aa:aa:aa')
    (context
     .ndb
     .interfaces[ifname]
     .rollback())
    assert not interface_exists(context.netns,
                                ifname=ifname,
                                address='00:11:22:aa:aa:aa')
    assert interface_exists(context.netns,
                            ifname=ifname,
                            address='00:11:22:33:44:55')
def test_simple_deps(context):

    ifname = context.new_ifname
    ipaddr = context.new_ipaddr
    router = context.new_ipaddr
    dst = str(context.ipnets[1].network)

    #
    # simple dummy interface with one address and
    # one dependent route
    #
    (context.ndb.interfaces.create(ifname=ifname, kind='dummy').set(
        'state', 'up').add_ip(address=ipaddr, prefixlen=24).commit())

    (context.ndb.routes.create(dst=dst, dst_len=24, gateway=router).commit())

    # check everything is in place
    assert interface_exists(context.netns, ifname=ifname)
    assert address_exists(context.netns, ifname=ifname, address=ipaddr)
    assert route_exists(context.netns, gateway=router, dst=dst, dst_len=24)

    # remove the interface
    iface = context.ndb.interfaces[ifname].remove().commit()

    # check there is no interface, no route
    assert not interface_exists(context.netns, ifname=ifname)
    assert not address_exists(context.netns, ifname=ifname, address=ipaddr)
    assert not route_exists(context.netns, gateway=router, dst=dst, dst_len=24)

    # revert the changes using the implicit last_save
    iface.rollback()

    assert interface_exists(context.netns, ifname=ifname)
    assert address_exists(context.netns, ifname=ifname, address=ipaddr)
    assert route_exists(context.netns, gateway=router, dst=dst, dst_len=24)
示例#6
0
def test_source_localhost_restart(context):
    '''
    The database must be operational after a complete
    restart of any source.
    '''
    require_user('root')
    ifname1 = context.new_ifname
    ifname2 = context.new_ifname
    ndb = context.ndb

    #
    # check that there are existing interfaces
    # loaded into the DB
    assert len(list(ndb.interfaces.dump()))
    #
    # create a dummy interface to prove the
    # source working
    (ndb
     .interfaces
     .create(ifname=ifname1, kind='dummy', state='up')
     .commit())
    #
    # an external check
    assert interface_exists(ifname=ifname1, state='up')
    #
    # internal checks
    assert ifname1 in ndb.interfaces
    assert ndb.interfaces[ifname1]['state'] == 'up'
    #
    # now restart the source
    # the reason should be visible in the log
    ndb.sources['localhost'].restart(reason='test')
    #
    # the interface must be in the DB (after the
    # source restart)
    assert ifname1 in ndb.interfaces
    #
    # create another one
    (ndb
     .interfaces
     .create(ifname=ifname2, kind='dummy', state='down')
     .commit())
    #
    # check the interface both externally and internally
    assert interface_exists(ifname=ifname2, state='down')
    assert ifname2 in ndb.interfaces
    assert ndb.interfaces[ifname2]['state'] == 'down'
    #
    # cleanup
    ndb.interfaces[ifname1].remove().commit()
    ndb.interfaces[ifname2].remove().commit()
    #
    # check
    assert not interface_exists(ifname=ifname1)
    assert not interface_exists(ifname=ifname2)
示例#7
0
def test_bridge(context):

    bridge = context.new_ifname
    brport = context.new_ifname
    spec_br = {'ifname': bridge, 'kind': 'bridge'}
    spec_pt = {'ifname': brport, 'kind': 'dummy'}

    (context.ndb.interfaces.create(**spec_br).commit())

    (context.ndb.interfaces.create(**spec_pt).set(
        'master', context.ndb.interfaces[spec_br]['index']).commit())

    assert interface_exists(context.netns, ifname=bridge)
    assert interface_exists(context.netns,
                            ifname=brport,
                            master=context.ndb.interfaces[spec_br]['index'])
示例#8
0
def test_scopes(context):

    ipaddr = context.new_ipaddr
    ifname = context.new_ifname
    table = context.table
    dst = '172.24.200.142'

    (context.ndb.interfaces.create(ifname=ifname, kind='dummy',
                                   state='up').add_ip(address=ipaddr,
                                                      prefixlen=24).commit())

    spec = {
        'dst': dst,
        'oif': context.ndb.interfaces[ifname]['index'],
        'dst_len': 32,
        'scope': 253
    }

    if table:
        spec['table'] = table

    (context.ndb.routes.create(**spec).commit())

    assert interface_exists(context.netns, ifname=ifname)
    assert route_exists(context.netns, **spec)

    (context.ndb.routes[spec].remove().commit())

    assert not route_exists(context.netns, **spec)
示例#9
0
def test_basic(context):

    ifaddr = context.new_ipaddr
    router = context.new_ipaddr
    ifname = context.new_ifname
    ipnet = str(context.ipnets[1].network)
    table = context.table

    (context
     .ndb
     .interfaces
     .create(ifname=ifname, kind='dummy', state='up')
     .ipaddr
     .create(address=ifaddr, prefixlen=24)
     .commit())

    spec = {'dst_len': 24,
            'dst': ipnet,
            'gateway': router}

    if table:
        spec['table'] = table

    (context
     .ndb
     .routes
     .create(**spec)
     .commit())

    assert interface_exists(context.netns, ifname=ifname)
    assert address_exists(context.netns, ifname=ifname, address=ifaddr)
    assert route_exists(context.netns, dst=ipnet, table=table or 254)
示例#10
0
def test_dummy(context):

    ifname = context.new_ifname
    spec = {'ifname': ifname, 'kind': 'dummy', 'address': '00:11:22:33:44:55'}
    context.ndb.interfaces.create(**spec).commit()
    assert interface_exists(context.netns,
                            ifname=ifname,
                            address='00:11:22:33:44:55')
示例#11
0
def test_cm_interface_change_assign(context):
    '''
    ::
        with interface as i:
            i['state'] = 'up'
    '''
    ifname = test_cm_interface_create(context)
    with context.ndb.interfaces[ifname] as i:
        i['state'] = 'up'
    assert interface_exists(context.netns, ifname=ifname, state='up')
示例#12
0
def test_cm_interface_change_set_kwarg(context):
    '''
    ::
        with interface as i:
            i.set(state='up')
    '''
    ifname = test_cm_interface_create(context)
    with context.ndb.interfaces[ifname] as i:
        i.set(state='up')
    assert interface_exists(context.netns, ifname=ifname, state='up')
示例#13
0
def test_del_ip_fail(context):
    ifname = context.new_ifname
    ipaddr = '%s/24' % context.new_ipaddr
    ipaddr_fail = '%s/24' % context.new_ipaddr

    (context.ndb.interfaces.create(ifname=ifname, kind='dummy',
                                   state='up').add_ip(ipaddr).commit())

    assert interface_exists(context.netns, ifname=ifname)
    assert address_exists(context.netns, ifname=ifname, address=ipaddr)

    try:
        (context.ndb.interfaces[ifname].del_ip(ipaddr_fail).commit())
        raise Exception('shall not pass')
    except KeyError:
        pass

    assert interface_exists(context.netns, ifname=ifname)
    assert address_exists(context.netns, ifname=ifname, address=ipaddr)
示例#14
0
def test_cm_interface_create(context):
    '''
    Create an interface using context manager syntax
    '''
    ifname = context.new_ifname
    with context.ndb.interfaces.create(ifname=ifname,
                                       kind='dummy',
                                       state='down'):
        pass
    assert interface_exists(context.netns, ifname=ifname, state='down')
    return ifname
示例#15
0
def test_vxlan(context):
    host = context.new_ifname
    vxlan = context.new_ifname
    spec_host = {'ifname': host, 'kind': 'dummy'}
    spec_vxlan = {'ifname': vxlan, 'kind': 'vxlan'}
    (context.ndb.interfaces.create(**spec_host).commit())
    (context.ndb.interfaces.create(**spec_vxlan).set(
        'vxlan_link', context.ndb.interfaces[spec_host]['index']).set(
            'vxlan_id', 101).set('vxlan_group',
                                 '239.1.1.1').set('vxlan_ttl', 16).commit())
    assert interface_exists(context.netns, ifname=vxlan)
示例#16
0
def test_veth_simple(context):
    ifname = context.new_ifname
    peername = context.new_ifname
    spec = {'ifname': ifname, 'peer': peername, 'kind': 'veth'}

    context.ndb.interfaces.create(**spec).commit()

    spec_ifl = {'ifname': ifname}
    spec_pl = {'ifname': peername}

    iflink = context.ndb.interfaces[spec_ifl]['link']
    plink = context.ndb.interfaces[spec_pl]['link']

    assert iflink == context.ndb.interfaces[spec_pl]['index']
    assert plink == context.ndb.interfaces[spec_ifl]['index']
    assert interface_exists(context.netns, ifname=ifname)
    assert interface_exists(context.netns, ifname=peername)

    context.ndb.interfaces[spec_ifl].remove().commit()

    assert not interface_exists(context.netns, ifname=ifname)
    assert not interface_exists(context.netns, ifname=peername)
示例#17
0
def test_basic_address(context):

    ifaddr = context.new_ipaddr
    ifname = context.new_ifname
    spec_if = {'ifname': ifname, 'kind': 'dummy', 'state': 'up'}
    i = (context.ndb.interfaces.create(**spec_if))
    i.commit()

    spec_ad = {'index': i['index'], 'address': ifaddr, 'prefixlen': 24}
    a = (context.ndb.addresses.create(**spec_ad))
    a.commit()
    assert interface_exists(context.netns, ifname=ifname)
    assert address_exists(context.netns, ifname=ifname, address=ifaddr)
示例#18
0
def test_localhost_implicit(context):
    ifname = context.new_ifname
    ipaddr = context.new_ipaddr
    nsname = context.new_nsname

    context.ndb.sources.add(netns=nsname)
    context.ndb.localhost = nsname

    (context.ndb.interfaces.create(ifname=ifname,
                                   kind='dummy').add_ip(address=ipaddr,
                                                        prefixlen=24).commit())

    assert interface_exists(nsname, ifname=ifname)
    assert address_exists(nsname, ifname=ifname, address=ipaddr)
示例#19
0
def test_multiple_interfaces(context):

    ifname1 = context.new_ifname
    ifname2 = context.new_ifname
    ipaddr1 = context.new_ipaddr
    ipaddr2 = context.new_ipaddr

    (context.ndb.begin().push(
        context.ndb.interfaces.create(ifname=ifname1, kind='dummy').set(
            state='up').set(address='00:11:22:aa:aa:aa').add_ip(
                address=ipaddr1, prefixlen=24),
        context.ndb.interfaces.create(ifname=ifname2, kind='dummy').set(
            state='up').set(address='00:11:22:bb:bb:bb').add_ip(
                address=ipaddr2, prefixlen=24)).commit())

    assert interface_exists(context.netns,
                            ifname=ifname1,
                            address='00:11:22:aa:aa:aa')
    assert interface_exists(context.netns,
                            ifname=ifname2,
                            address='00:11:22:bb:bb:bb')
    assert address_exists(context.netns, ifname=ifname1, address=ipaddr1)
    assert address_exists(context.netns, ifname=ifname2, address=ipaddr2)
示例#20
0
def test_vlan_deps(context):

    if_host = context.new_ifname
    if_vlan = context.new_ifname
    ifaddr1 = context.new_ipaddr
    ifaddr2 = context.new_ipaddr
    router = context.new_ipaddr
    dst = str(context.ipnets[1].network)

    (context
     .ndb
     .interfaces
     .create(ifname=if_host, kind='dummy', state='up')
     .commit())

    (context
     .ndb
     .interfaces
     .create(ifname=if_vlan,
             kind='vlan',
             state='up',
             vlan_id=1001,
             link=if_host)
     .add_ip(address=ifaddr1, prefixlen=24)
     .add_ip(address=ifaddr2, prefixlen=24)
     .commit())

    (context
     .ndb
     .routes
     .create(dst=dst, dst_len=24, gateway=router)
     .commit())

    # check everything is in place
    assert interface_exists(context.netns, ifname=if_host)
    assert interface_exists(context.netns, ifname=if_vlan)
    assert address_exists(context.netns, ifname=if_vlan, address=ifaddr1)
    assert address_exists(context.netns, ifname=if_vlan, address=ifaddr2)
    assert route_exists(context.netns, dst=dst, gateway=router)

    # remove the interface
    iface = context.ndb.interfaces[if_host].remove().commit()

    # check there is no interface, no route
    assert not interface_exists(context.netns, ifname=if_host)
    assert not interface_exists(context.netns, ifname=if_vlan)
    assert not address_exists(context.netns, ifname=if_vlan, address=ifaddr1)
    assert not address_exists(context.netns, ifname=if_vlan, address=ifaddr2)
    assert not route_exists(context.netns, dst=dst, gateway=router)

    # revert the changes using the implicit last_save
    iface.rollback()
    assert interface_exists(context.netns, ifname=if_host)
    assert interface_exists(context.netns, ifname=if_vlan)
    assert address_exists(context.netns, ifname=if_vlan, address=ifaddr1)
    assert address_exists(context.netns, ifname=if_vlan, address=ifaddr2)
    assert route_exists(context.netns, dst=dst, gateway=router)
示例#21
0
def test_veth_spec(context):
    ifname = context.new_ifname
    peername = context.new_ifname
    nsname = context.new_nsname

    context.ndb.sources.add(netns=nsname)

    spec = {
        'ifname': ifname,
        'kind': 'veth',
        'peer': {
            'ifname': peername,
            'address': '00:11:22:33:44:55',
            'net_ns_fd': nsname
        }
    }
    (context.ndb.interfaces.create(**spec).commit())

    (context.ndb.interfaces.wait(target=nsname, ifname=peername))

    iflink = context.ndb.interfaces[{'ifname': ifname}]['link']
    plink = context.ndb.interfaces[{
        'target': nsname,
        'ifname': peername
    }]['link']

    assert iflink == (context.ndb.interfaces[{
        'target': nsname,
        'ifname': peername
    }]['index'])
    assert plink == (context.ndb.interfaces[{'ifname': ifname}]['index'])

    assert interface_exists(context.netns, ifname=ifname)
    assert interface_exists(nsname, ifname=peername)
    assert not interface_exists(nsname, ifname=ifname)
    assert not interface_exists(context.netns, ifname=peername)

    (context.ndb.interfaces[{'ifname': ifname}].remove().commit())

    assert not interface_exists(context.netns, ifname=ifname)
    assert not interface_exists(nsname, ifname=ifname)
    assert not interface_exists(context.netns, ifname=peername)
    assert not interface_exists(nsname, ifname=peername)

    context.ndb.sources.remove(nsname)
示例#22
0
def test_fail(context):

    ifname = context.new_ifname
    kind = context.new_ifname
    spec = {'ifname': ifname, 'kind': kind}
    ifobj = context.ndb.interfaces.create(**spec)
    save = dict(ifobj)

    try:
        ifobj.commit()
    except NetlinkError as e:
        assert e.code == 95  # Operation not supported

    assert save == dict(ifobj)
    assert ifobj.state == 'invalid'
    assert not interface_exists(context.netns, ifname=ifname)
示例#23
0
def test_bridge_deps(context):

    if_br0 = context.new_ifname
    if_br0p0 = context.new_ifname
    if_br0p1 = context.new_ifname
    ifaddr1 = context.new_ipaddr
    ifaddr2 = context.new_ipaddr
    router = context.new_ipaddr
    dst = str(context.ipnets[1].network)

    with context.ndb.interfaces as i:
        i.create(ifname=if_br0p0, kind='dummy', state='up').commit()
        i.create(ifname=if_br0p1, kind='dummy', state='up').commit()
        (i.create(ifname=if_br0, kind='bridge', state='up')
         .add_port(if_br0p0)
         .add_port(if_br0p1)
         .add_ip(address=ifaddr1, prefixlen=24)
         .add_ip(address=ifaddr2, prefixlen=24)
         .commit())

    (context
     .ndb
     .routes
     .create(dst=dst, dst_len=24, gateway=router)
     .commit())

    assert interface_exists(context.netns, ifname=if_br0)
    assert interface_exists(context.netns, ifname=if_br0p0)
    assert interface_exists(context.netns, ifname=if_br0p1)
    assert address_exists(context.netns, ifname=if_br0, address=ifaddr1)
    assert address_exists(context.netns, ifname=if_br0, address=ifaddr2)
    assert route_exists(context.netns, gateway=router, dst=dst, dst_len=24)

    # remove the interface
    iface = context.ndb.interfaces[if_br0].remove().commit()

    assert not interface_exists(context.netns, ifname=if_br0)
    assert not address_exists(context.netns, ifname=if_br0, address=ifaddr1)
    assert not address_exists(context.netns, ifname=if_br0, address=ifaddr2)
    assert not route_exists(context.netns, gateway=router, dst=dst, dst_len=24)

    # revert the changes using the implicit last_save
    iface.rollback()
    assert interface_exists(context.netns, ifname=if_br0)
    assert interface_exists(context.netns, ifname=if_br0p0)
    assert interface_exists(context.netns, ifname=if_br0p1)
    assert address_exists(context.netns, ifname=if_br0, address=ifaddr1)
    assert address_exists(context.netns, ifname=if_br0, address=ifaddr2)
    assert route_exists(context.netns, gateway=router, dst=dst, dst_len=24)
示例#24
0
def test_source_netns_restart(context):
    '''
    Netns sources should be operational after restart as well
    '''
    require_user('root')
    nsname = context.new_nsname
    #
    # simple `context.new_ifname` returns ifname only for the main
    # netns, if we want to register the name in a netns, we should
    # use `context.register(netns=...)`
    ifname = context.register(netns=nsname)
    ndb = context.ndb

    #
    # add a netns source, the netns will be created automatically
    ndb.sources.add(netns=nsname)
    #
    # check the interfaces from the netns are loaded into the DB
    assert len(list(ndb.interfaces.dump().filter(target=nsname)))
    #
    # restart the DB
    ndb.sources[nsname].restart(reason='test')
    #
    # check the netns interfaces again
    assert len(list(ndb.interfaces.dump().filter(target=nsname)))
    #
    # create an interface in the netns
    (
        ndb.interfaces.create(
            target=nsname, ifname=ifname, kind='dummy', state='up'
        ).commit()
    )
    #
    # check the interface
    assert interface_exists(nsname, ifname=ifname)
    assert (
        ndb.interfaces[{'target': nsname, 'ifname': ifname}]['state'] == 'up'
    )
示例#25
0
def test_move(context):
    ifname = context.new_ifname
    ifaddr = context.new_ipaddr
    nsname = context.new_nsname

    context.ndb.sources.add(netns=nsname)

    # create the interface
    (context.ndb.interfaces.create(ifname=ifname, kind='dummy').commit())

    # move it to a netns
    (context.ndb.interfaces[ifname].set('net_ns_fd', nsname).commit())

    # setup the interface only when it is moved
    (context.ndb.interfaces.wait(target=nsname, ifname=ifname).set(
        'state',
        'up').set('address',
                  '00:11:22:33:44:55').add_ip('%s/24' % ifaddr).commit())

    assert interface_exists(nsname,
                            ifname=ifname,
                            state='up',
                            address='00:11:22:33:44:55')
示例#26
0
def test_vrf(context):
    vrf = context.new_ifname
    spec = {'ifname': vrf, 'kind': 'vrf'}
    (context.ndb.interfaces.create(**spec).set('vrf_table', 42).commit())
    assert interface_exists(context.netns, ifname=vrf)
示例#27
0
def test_view_cache(context):
    '''
    NDB stores all the info in an SQL database, and instantiates
    python objects only upon request, since it isn't cheap.
    References to the created objects are stored in the object
    cache until expired.

    This test checks is the cache works as expected. Initially
    there should be no references in the cache, check if the
    references are properly cached and expired in time.
    '''
    require_user('root')
    ifname1 = context.new_ifname
    ifname2 = context.new_ifname

    ndb = context.ndb

    #
    # the cache is empty from the beginning
    assert len(list(ndb.interfaces.cache)) == 0
    #
    # create test interfaces
    ndb.interfaces.create(ifname=ifname1, kind='dummy').commit()
    ndb.interfaces.create(ifname=ifname2, kind='dummy').commit()
    assert interface_exists(ifname=ifname1)
    assert interface_exists(ifname=ifname2)
    #
    # the interface object must not be cached, as they
    # weren't referenced yet
    assert len(list(ndb.interfaces.cache)) == 0
    #
    # setup the cache expiration time
    ce = config.cache_expire  # save the old value
    config.cache_expire = 1  # set the new one
    #
    # access the interfaces via __getitem__() -- this must
    # create objects and cache the references
    assert ndb.interfaces[ifname1] is not None
    assert ndb.interfaces[ifname2] is not None
    #
    # both references must be in the cache now
    assert len(list(ndb.interfaces.cache)) == 2
    #
    # expire the cache
    time.sleep(1)
    #
    # access the second interface to trigger the
    # cache invalidation
    assert ndb.interfaces[ifname2] is not None
    #
    # ifname1 must be out of the cache now as not
    # accessed within the timeout
    #
    # only ifname2 must remain
    assert len(list(ndb.interfaces.cache)) == 1
    assert list(ndb.interfaces.cache.items())[0][1]['ifname'] == ifname2
    #
    # restore the environment
    config.cache_expire = ce
    ndb.interfaces[ifname1].remove().commit()
    ndb.interfaces[ifname2].remove().commit()

    #
    # check that the interfaces are cleaned up from the system
    assert not interface_exists(ifname=ifname1)
    assert not interface_exists(ifname=ifname2)