NDB module

NDB is a high level network management module. IT allows to manage interfaces, routes, addresses etc. of connected systems, containers and network namespaces.

In a nutshell, NDB collects and aggregates netlink events in an SQL database, provides Python objects to reflect the system state, and applies changes back to the system. The database expects updates only from the sources, no manual SQL updates are expected normally.

_images/aafig-80bc0b850cd3f4d027d8d72e97c7fc1b52fe5bca.svg

NDB can work with remote systems via ssh, in that case mitogen module is required. It is possible to connect also OpenBSD and FreeBSD systems, but in read-only mode for now.

Note

See also the module choice guide: IPRoute or NDB

Quick start

The goal of NDB is to provide an easy access to RTNL info and entities via Python objects, like pyroute2.ndb.objects.interface (see also: Network interfaces), pyroute2.ndb.objects.route (see also: Routes management) etc. These objects do not only reflect the system state for the time of their instantiation, but continuously monitor the system for relevant updates. The monitoring is done via netlink notifications, thus no polling. Also the objects allow to apply changes back to the system and rollback the changes.

On the other hand it’s too expensive to create Python objects for all the available RTNL entities, e.g. when there are hundreds of interfaces and thousands of routes. Thus NDB creates objects only upon request, when the user calls .create() to create new objects or runs ndb.<view>[selector] (e.g. ndb.interfaces[‘eth0’]) to access an existing object.

To list existing RTNL entities NDB uses objects of the class RecordSet that yield individual Record objects for every entity (see also: Record list filters). An object of the Record class is immutable, doesn’t monitor any updates, doesn’t contain any links to other objects and essentially behaves like a simple named tuple.

_images/aafig-db02be09e1d33d12b493455bdfd27b7ad0692510.svg

Here are some simple NDB usage examples. More info see in the reference documentation below.

Print all the interface names on the system, assume we have an NDB instance ndb:

for interface in ndb.interfaces.dump():
    print(interface.ifname)

Print the routing information in the CSV format:

for line in ndb.routes.summary().format('csv'):
    print(record)

Note

More on report filtering and formatting: Record list filters

Note

Since 0.5.11; versions 0.5.10 and earlier used syntax summary(format=’csv’, match={…})

Print IP addresses of interfaces in several network namespaces as:

nslist = ['netns01',
          'netns02',
          'netns03']

for nsname in nslist:
    ndb.sources.add(netns=nsname)

for line in ndb.addresses.summary().format('json'):
    print(line)

Add an IP address on an interface:

(ndb
 .interfaces['eth0']
 .add_ip('10.0.0.1/24')
 .commit())
# ---> <---  NDB waits until the address actually

Change an interface property:

(ndb
 .interfaces['eth0']
 .set('state', 'up')
 .set('address', '00:11:22:33:44:55')
 .commit())
# ---> <---  NDB waits here for the changes to be applied

# same as above, but using properties as argument names
(ndb
 .interfaces['eth0']
 .set(state='up')
 .set(address='00:11:22:33:44:55')
 .commit())

# ... or with another syntax
with ndb.interfaces['eth0'] as i:
    i['state'] = 'up'
    i['address'] = '00:11:22:33:44:55'
# ---> <---  the commit() is called authomatically by
#            the context manager's __exit__()

Reference

work in progress