def teardown(self): with NDB() as indb: if self.nsname: (indb .sources .add(netns=self.nsname)) for link in reversed(self.interfaces): try: (indb .interfaces[link] .remove() .commit()) except Exception: pass for link in reversed(self.interfaces): try: (indb .interfaces[self.getspec(ifname=link)] .remove() .commit()) except Exception: pass self.ndb.close() for net in self.ipnets: free_network(net) if self.nsname: netns.remove(self.nsname)
def test_basic(context): ifname = context.new_ifname ifaddr1 = context.new_ipaddr ifaddr2 = context.new_ipaddr ifaddr3 = context.new_ipaddr nsname = context.new_nsname context.ndb.sources.add(netns=nsname) (context.ndb.interfaces.create( target=nsname, ifname=ifname, kind='dummy').ipaddr.create(address=ifaddr1, prefixlen=24).create( address=ifaddr2, prefixlen=24).create(address=ifaddr3, prefixlen=24).commit()) with NDB(sources=[{ 'target': 'localhost', 'netns': nsname, 'kind': 'netns' }]) as ndb: if_idx = ndb.interfaces[ifname]['index'] addr1_idx = ndb.addresses['%s/24' % ifaddr1]['index'] addr2_idx = ndb.addresses['%s/24' % ifaddr2]['index'] addr3_idx = ndb.addresses['%s/24' % ifaddr3]['index'] assert if_idx == addr1_idx == addr2_idx == addr3_idx
def test_view_cache(self): require_user('root') log_id = str(uuid.uuid4()) ifname1 = uifname() ifname2 = uifname() with NDB(log='../ndb-%s-%s.log' % (os.getpid(), log_id), rtnl_debug=True) as 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() # the interfaces must not be cached assert len(list(ndb.interfaces.cache)) == 0 # setup the cache expiration time ce = config.cache_expire config.cache_expire = 1 # access the interfaces via __getitem__() assert ndb.interfaces[ifname1] is not None assert ndb.interfaces[ifname2] is not None # both must be in the cache 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 # only ifname2 must remain in the cache assert len(list(ndb.interfaces.cache)) == 1 # restore the environment config.cache_expire = ce ndb.interfaces[ifname1].remove().commit() ndb.interfaces[ifname2].remove().commit()
def test_basic(self): ifname = uifname() ifaddr1 = self.ifaddr() ifaddr2 = self.ifaddr() ifaddr3 = self.ifaddr() (self .ndb .interfaces .create(target=self.netns, ifname=ifname, kind='dummy') .ipaddr .create(address=ifaddr1, prefixlen=24) .create(address=ifaddr2, prefixlen=24) .create(address=ifaddr3, prefixlen=24) .commit()) with NDB(sources=[{'target': 'localhost', 'netns': self.netns, 'kind': 'netns'}]) as ndb: if_idx = ndb.interfaces[ifname]['index'] addr1_idx = ndb.addresses['%s/24' % ifaddr1]['index'] addr2_idx = ndb.addresses['%s/24' % ifaddr2]['index'] addr3_idx = ndb.addresses['%s/24' % ifaddr3]['index'] assert if_idx == addr1_idx == addr2_idx == addr3_idx
def init(config): if isinstance(config, basestring): config = json.loads(config) else: config = json.load(config) hostname = config['local'].get('hostname', socket.gethostname()) messenger = Messenger( config['local']['id'], Transport(config['local']['address'], config['local']['port'])) for target in config['local'].get('targets', []): messenger.targets.add(target) if not messenger.targets: messenger.targets.add(hostname) for peer in config.get('peers', []): messenger.add_peer(*peer) sources = config['local'].get('sources') if sources is None: sources = [{'target': hostname, 'kind': 'local'}] return NDB(log=config.get('log', 'debug'), sources=sources, messenger=messenger)
def ifup(self): """ Bring the network interface up for this node """ with NDB() as ndb: # bring it up and wait until success ndb.interfaces[self.vethPeer].set(state="up").commit()
def ifdown(self): """ Bring the network interface down for this node """ with NDB() as ndb: # bring it down and wait until success ndb.interfaces[self.vethPeer].set(state="down").commit()
def test_multiple_sources(self): # NB: no 'localhost' record -- important # sources = [{ 'target': 'localhost0', 'kind': 'local' }, { 'target': 'localhost1', 'kind': 'remote' }, { 'target': 'localhost2', 'kind': 'remote' }] # check all the views # with NDB(sources=sources) as ndb: assert len(list(ndb.interfaces.dump())) assert len(list(ndb.neighbours.dump())) assert len(list(ndb.addresses.dump())) assert len(list(ndb.routes.dump())) for source in ndb.sources: assert ndb.sources[source].nl.closed
def setup(self): require_user('root') self.if_simple = None self.interfaces = self.create_interfaces() self.ndb = NDB(db_provider=self.db_provider, db_spec=self.db_spec, sources=self.nl_class(**self.nl_kwarg))
def test_multiple_sources(context): ''' NDB should work with multiple netlink sources Check that it actually works: * with multiple sources of different kind * without the default "localhost" RTNL source ''' nsname = context.new_nsname # # NB: no 'localhost' record -- important ! sources = [ {'target': 'localhost0', 'kind': 'local'}, {'target': 'localhost1', 'kind': 'netns', 'netns': nsname}, {'target': 'localhost2', 'kind': 'local'}, ] ndb = None # # check that all the view has length > 0 # that means that the sources are working with NDB(sources=sources) as ndb: assert len(list(ndb.interfaces.dump())) assert len(list(ndb.neighbours.dump())) assert len(list(ndb.addresses.dump())) assert len(list(ndb.routes.dump())) # here NDB() gets closed # # # the `ndb` variable still references the closed # NDB() object from the code block above, check # that all the sources are closed too for source in ndb.sources: assert ndb.sources[source].nl.closed
def setup(self): require_user('root') self.ipnets = [allocate_network() for _ in range(5)] self.ipranges = [[str(x) for x in net] for net in self.ipnets] self.ndb = NDB(db_provider=self.db_provider, db_spec=self.db_spec, rtnl_log=True, sources=self.nl_class(**self.nl_kwarg))
def list_wg(): ndb = NDB() if_wgs = [] for _, _, index, ifname, mac, _, typ in ndb.interfaces.summary(): if typ == "wireguard": if_wgs.append((index, ifname, typ)) return if_wgs
def create_vlan(name, parent, tag): with NDB(log="off") as ndb: ndb.interfaces[parent].set("state", "up").commit() # make sure parent is up ndb.interfaces.create(ifname=name, link=parent, vlan_id=tag, kind="vlan").set("state", "up").commit()
def __init__(self, request, tmpdir, **kwarg): self.spec = SpecContextManager(request, tmpdir) self.netns = None # # the cleanup registry self.interfaces = {} self.namespaces = {} if 'log' not in kwarg: kwarg['log'] = self.spec.log_spec if 'rtnl_debug' not in kwarg: kwarg['rtnl_debug'] = True kind = 'local' self.table = None kwarg['db_provider'] = 'sqlite3' kwarg['db_spec'] = ':memory:' if hasattr(request, 'param'): if isinstance(request.param, ContextParams): kind = request.param.target self.table = request.param.table kwarg['db_provider'] = request.param.db_provider kwarg['db_spec'] = request.param.db_spec elif isinstance(request.param, (tuple, list)): kind, self.table = request.param else: kind = request.param if kind == 'local': sources = [{'target': 'localhost', 'kind': 'local'}] elif kind == 'netns': self.netns = self.new_nsname sources = [{ 'target': 'localhost', 'kind': 'netns', 'netns': self.netns }] else: sources = None if sources is not None: kwarg['sources'] = sources # # select the DB to work on db_name = os.environ.get('PYROUTE2_TEST_DBNAME') if isinstance(db_name, basestring) and len(db_name): kwarg['db_provider'] = 'psycopg2' kwarg['db_spec'] = {'dbname': db_name} # # this instance is to be tested, so do NOT use it # in utility methods self.ndb = NDB(**kwarg) self.ipr = self.ndb.sources['localhost'].nl.clone() # # IPAM self.ipnets = [allocate_network() for _ in range(5)] self.ipranges = [[str(x) for x in net] for net in self.ipnets]
def __init__(self, address='localhost', port=8080, debug=None, sources=None): self.sessions = {} self.ndb = NDB(debug=debug, sources=sources) self.ndb.config = {'show_format': 'json'} HTTPServer.__init__(self, (address, port), Handler)
def setup(self): require_user('root') self.ipnets = [allocate_network() for _ in range(5)] self.ipranges = [[str(x) for x in net] for net in self.ipnets] self.ndb = NDB(db_provider=self.db_provider, db_spec=self.db_spec, debug=True) self.ndb.log('../ndb-%s-%s.log' % (os.getpid(), id(self.ndb))) self.interfaces = []
def ifname(net: Network) -> str: 'Returns ifname of net["cidr"] on the current machine' ndb = NDB() cidr_route = ndb.routes[net["cidr"]] addr_route = f'{cidr_route["prefsrc"]}/{cidr_route["dst_len"]}' ifname = ndb.addresses[addr_route]['label'] ndb.close() return ifname
def test_respawn_ndb_sqlite3(self): for _ in range(RESPAWNS): with NDB() as i: assert len(tuple(i.interfaces.summary())) assert len(tuple(i.addresses.summary())) assert len(tuple(i.routes.summary())) assert len(tuple(i.interfaces.dump().format('csv'))) assert len(tuple(i.addresses.dump().format('csv'))) assert len(tuple(i.routes.dump().format('csv')))
def test_respawn_ndb_sqlite3(self): for _ in range(RESPAWNS): with NDB() as i: assert len(i.interfaces.summary()) assert len(i.addresses.summary()) assert len(i.routes.summary()) assert len(i.interfaces.csv()) assert len(i.addresses.csv()) assert len(i.routes.csv())
def _add_interface_to_bridge(self, bridge, interface): """ Adds the given interface to the bridge. In our usecase, this interface is usually the peer end of a veth pair with the other end inside a network namespace, in which case after calling this function the namespace will be able to communicate with the other nodes in the virtual network. """ with NDB() as ndb: ndb.interfaces[bridge].add_port(interface).commit() ndb.interfaces[interface].set(state="up").commit()
def setup(self): require_user('root') self.interfaces = [] self.log_id = str(uuid.uuid4()) self.ipnets = [allocate_network() for _ in range(2)] self.ipranges = [[str(x) for x in net] for net in self.ipnets] self.ndb = NDB(db_provider=self.db_provider, db_spec=self.db_spec, log='../ndb-%s-%s.log' % (os.getpid(), self.log_id), debug=True)
def _add_bridge(self, name, address, prefixLen): """ Creates a bridge with the given name, address, and netmask perfix length. """ _remove_interface_if_exists(name) with NDB() as ndb: (ndb.interfaces.create( ifname=name, kind="bridge", state="up").add_ip("%s/%s" % (address, prefixLen)).commit())
def create_dummy_interface(interface, ip_addresses): with NDB(log='on') as ndb: nbd_if = ndb.interfaces.create(ifname=interface, kind="dummy") for ip_address in ip_addresses: nbd_if = nbd_if.add_ip( "%s/%s" % (ip_address.ip.exploded, "32" if isinstance( ip_address.ip, ipaddress.IPv4Address) else "128")) nbd_if.set('state', 'up') nbd_if.commit()
def __init__(self, *argv, **kwarg): if argv or kwarg: log.warning('%s does not support IPDB parameters, ignoring', self.__class__.__name__) if len(argv) > 0 or 'nl' in kwarg: log.warning('%s does not support shared netlink sources,' ' ignoring `nl` and starting with local IPRoute', self.__class__.__name__) self._ndb = NDB() self.interfaces = Interfaces(self._ndb.interfaces)
def setup(self): require_user('root') self.netns = str(uuid.uuid4()) self.ipnets = [allocate_network() for _ in range(3)] self.ipranges = [[str(x) for x in net] for net in self.ipnets] self.sources = [{'target': 'localhost'}, {'netns': self.netns}] self.ndb = NDB(db_provider=self.db_provider, db_spec=self.db_spec, sources=self.sources, debug=True) self.ndb.log('../ndb-%s-%s.log' % (os.getpid(), id(self.ndb)))
def _remove_interface_if_exists(name): """ If the given interface exists, brings it down and removes it. Otherwise just returns silently. A bridge is also an interface, so this can be used for removing bridges too. """ with NDB() as ndb: if name in ndb.interfaces: try: ndb.interfaces[name].remove().commit() except netlink.exceptions.NetlinkError: pass
def test_postgres_fail(spec): try: NDB(db_provider='postgres', db_spec={ 'dbname': 'some-nonsense-db-name' }, log=spec.log_spec).close() except psycopg2.OperationalError: return raise Exception('postgresql exception was expected')
def __init__(self, address='localhost', port=8080, sources=None, log=None, auth_strict=False, auth_plugins=None): self.sessions = {} self.auth_strict = auth_strict self.auth_plugins = auth_plugins or {} self.ndb = NDB(sources=sources, log=log) self.ndb.config = {'show_format': 'json'} HTTPServer.__init__(self, (address, port), Handler)
def __init__(self, stdout=None, log=None, sources=None): global HAS_READLINE self.db = NDB(log=log, sources=sources) self.db.config = {'show_format': 'json'} self.stdout = stdout or sys.stdout self.session = Session(self.db, self.stdout, self.set_prompt) self.matches = [] self.isatty = sys.stdin.isatty() self.prompt = '' self.set_prompt() code.InteractiveConsole.__init__(self) if HAS_READLINE: readline.parse_and_bind('tab: complete') readline.set_completer(self.completer) readline.set_completion_display_matches_hook(self.display)
def _assert_test_view(self, ifname, ifaddr): with NDB(sources=[{ 'target': 'localhost', 'netns': self.netns, 'kind': 'netns' }]) as ndb: (if_idx, if_state, if_addr, if_flags) = ndb.interfaces[ifname].fields('index', 'state', 'address', 'flags') addr_idx = ndb.addresses['%s/24' % ifaddr]['index'] assert if_idx == addr_idx assert if_state == 'up' assert if_flags & 1 assert if_addr == '00:11:22:33:44:55'