AutoNetkit API tutorial

Written for AutoNetkit 0.8

Create Network


In [1]:
import autonetkit
anm = autonetkit.ANM()

In [2]:
g_in = anm.add_overlay("input")
nodes = ['r1', 'r2', 'r3', 'r4', 'r5']

g_in.add_nodes_from(nodes)
g_in.update(device_type = "router", asn=1)
g_in.update("r5", asn = 2)

In [3]:
positions = {'r1': (10, 79),
 'r2': (226, 25),
 'r3': (172, 295),
 'r4': (334, 187),
 'r5': (496, 349)}

for n in g_in:
    n.x, n.y = positions[n]

autonetkit.update_http(anm)

In [4]:
edges = [("r1", "r2"), ("r2", "r4"), ("r1", "r3"), 
         ("r3", "r4"), ("r3", "r5"), ("r4", "r5")]
g_in.add_edges_from(edges)
g_in.allocate_interfaces()


INFO Automatically assigning input interfaces
INFO:ANK:Automatically assigning input interfaces

In [5]:
autonetkit.update_http(anm)

In [6]:
g_phy = anm['phy']
g_phy.add_nodes_from(g_in, retain=["asn", "device_type", "x", "y"])
g_phy.update(use_ipv4 = True, host = "localhost", platform = "netkit", syntax = "quagga")

g_phy.add_edges_from(g_in.edges())
autonetkit.update_http(anm)

In [7]:
g_ospf = anm.add_overlay("ospf")
g_ospf.add_nodes_from(g_in.routers())
g_ospf.add_edges_from(e for e in g_in.edges()
                      if e.src.asn == e.dst.asn)
autonetkit.update_http(anm)

In [8]:
g_ebgp = anm.add_overlay("ebgp_v4", directed = True)
g_ebgp.add_nodes_from(g_in.routers())
edges = [e for e in g_in.edges()
         if e.src.asn != e.dst.asn]
# Add in both directions
g_ebgp.add_edges_from(edges, bidirectional = True)
autonetkit.update_http(anm)

In [10]:
g_ibgp = anm.add_overlay("ibgp_v4", directed = True)
g_ibgp.add_nodes_from(g_in.routers())
edges = [(s,t) for s in g_ibgp for t in g_ibgp
         # belong to same ASN, but not self-loops
         if s != t and s.asn == t.asn]

# Add in both directions
g_ibgp.add_edges_from(edges, bidirectional = True)
autonetkit.update_http(anm)

In [11]:
import autonetkit.ank as ank_utils
g_ipv4 = anm.add_overlay("ipv4")
g_ipv4.add_nodes_from(g_in)
g_ipv4.add_edges_from(g_in.edges())

# Split the point-to-point edges to add a collision domain
edges_to_split = [edge for edge in g_ipv4.edges()
                  if edge.attr_both('is_l3device')]
for edge in edges_to_split:
    edge.split = True  # mark as split for use in building nidb
    
split_created_nodes = list(ank_utils.split(g_ipv4, edges_to_split,
    retain=['split'], id_prepend='cd'))

for node in split_created_nodes:
    # Set the co-ordinates using 'x', 'y' of g_in
    # based on neighbors in g_ipv4
    node.x = ank_utils.neigh_average(g_ipv4, node, 'x', g_in)
    node.y = ank_utils.neigh_average(g_ipv4, node, 'y', g_in)
    # Set most frequent of asn property in g_phy
    # ASN is used to allocate IPs
    node.asn = ank_utils.neigh_most_frequent(g_ipv4, node,
                                             'asn', g_phy)
    node.collision_domain = True
    
# Now use allocation plugin
import autonetkit.plugins.ipv4 as ipv4
ipv4.allocate_infra(g_ipv4)
ipv4.allocate_loopbacks(g_ipv4)

autonetkit.update_http(anm)


INFO Allocating v4 Infrastructure IPs
INFO:ANK:Allocating v4 Infrastructure IPs
INFO Allocating v4 Primary Host loopback IPs
INFO:ANK:Allocating v4 Primary Host loopback IPs

In [12]:
# Now construct NIDB
nidb = autonetkit.NIDB()
# NIDB is separate to the ANM -> copy over more properties
retain = ['label', 'host', 'platform', 'x', 'y', 'asn', 'device_type']
nidb.add_nodes_from(g_phy, retain=retain)

# Usually have a base g_ip which has structure
# allocate to g_ipv4, g_ipv6
nidb.add_nodes_from(g_phy, retain=retain)
retain.append("subnet") # also copy across subnet
nidb.add_nodes_from(g_ipv4.nodes("collision_domain"), retain=retain)
nidb.add_edges_from(g_ipv4.edges())

# Also need to copy across the collision domains

autonetkit.update_http(anm, nidb)

In [13]:
import autonetkit.compilers.platform.netkit as pl_netkit
host = "localhost"

platform_compiler = pl_netkit.NetkitCompiler(nidb, anm, host)
platform_compiler.compile()


INFO Compiling Netkit for localhost
INFO:ANK:Compiling Netkit for localhost

In [14]:
import autonetkit.render
autonetkit.render.render(nidb)


INFO Rendering Network
INFO:ANK:Rendering Network

The output files are put

into rendered/localhost/netkit

For instance:

├── lab.conf
├── r1
│   ├── etc
│   │   ├── hostname
│   │   ├── shadow
│   │   ├── ssh
│   │   │   └── sshd_config
│   │   └── zebra
│   │       ├── bgpd.conf
│   │       ├── daemons
│   │       ├── isisd.conf
│   │       ├── motd.txt
│   │       ├── ospfd.conf
│   │       └── zebra.conf
│   └── root
├── r1.startup
├── r2
│   ├── etc
│   │   ├── hostname
│   │   ├── shadow
│   │   ├── ssh
│   │   │   └── sshd_config
│   │   └── zebra
│   │       ├── bgpd.conf
│   │       ├── daemons
│   │       ├── isisd.conf
│   │       ├── motd.txt
│   │       ├── ospfd.conf
│   │       └── zebra.conf
│   └── root
├── r2.startup

Can also write our own compiler and templates:


In [15]:
# AutoNetkit renderer expects filenames for templates
# uses the Mako template format
router_template_str = """Router rendered on ${date} by ${version_banner}
% for interface in node.interfaces:
interface ${interface.id}
    description ${interface.description}
    ip address ${interface.ipv4_address} netmask ${interface.ipv4_subnet.netmask}
% endfor
!
router ospf ${node.ospf.process_id}
    % for link in node.ospf.ospf_links:
    network ${link.network.cidr} area ${link.area}
    % endfor
!
router bgp ${node.asn}
% for neigh in node.bgp.ibgp_neighbors:
  ! ${neigh.neighbor}
  neighbor ${neigh.loopback} remote-as ${neigh.asn}
  neighbor ${neigh.loopback} update-source ${node.loopback}
  neighbor ${neigh.loopback} next-hop-self
% endfor
!
% for neigh in node.bgp.ebgp_neighbors:
  ! ${neigh.neighbor}
  neighbor ${neigh.dst_int_ip} remote-as ${neigh.asn}
  neighbor ${neigh.dst_int_ip} update-source ${neigh.local_int_ip}
% endfor
!    
"""

router_template = "router.mako"
with open(router_template, "w") as fh:
    fh.write(router_template_str)

In [16]:
from autonetkit.compilers.device import router_base
class simple_router_compiler(router_base.RouterCompiler):
    lo_interface = 'lo:1'

    def interfaces(self, node):
        ipv4_node = self.anm['ipv4'].node(node)
        phy_node = self.anm['phy'].node(node)

        super(simple_router_compiler, self).interfaces(node)
        if node.is_l3device:
            node.loopback_zero.id = self.lo_interface
            node.loopback_zero.description = 'Loopback'
            node.loopback_zero.ipv4_address = ipv4_node.loopback
            node.loopback_zero.ipv4_subnet = node.loopback_subnet

In [17]:
topology_template_str = """Topology rendered on ${date} by ${version_banner}
% for host in topology.hosts:
host: ${host}
% endfor
"""

topology_template = "topology.mako"
with open(topology_template, "w") as fh:
    fh.write(topology_template_str)

In [18]:
from autonetkit.compilers.platform import platform_base
import netaddr
from autonetkit.nidb import config_stanza

class simple_platform_compiler(platform_base.PlatformCompiler):
    def compile(self):
        mgmt_address_block = netaddr.IPNetwork("172.16.0.0/16").iter_hosts()
        
        rtr_comp = simple_router_compiler(self.nidb, self.anm)
        
        for node in nidb.routers(host=host):
            node.mgmt_ip = mgmt_address_block.next()
            for index, interface in enumerate(node.physical_interfaces):
                interface.id = "eth%s" % index
            
            # specify router template
            node.render.template = router_template
            node.render.dst_folder = "rendered"
            node.render.dst_file = "%s.conf" % node
            # and compile
            rtr_comp.compile(node)
            node.dump()
            
                
        # and the topology
        lab_topology = self.nidb.topology[self.host]
        # template settings for the rendered
        lab_topology.render_template = topology_template
        lab_topology.render_dst_folder = "rendered"
        lab_topology.render_dst_file = "lab.conf"
        
        lab_topology.hosts = []
        for node in nidb.routers(host=host):
            lab_topology.hosts.append(node)
            
        # Can also deduce links (by condensing the CDs)

In [19]:
sim_plat = simple_platform_compiler(nidb, anm, "localhost")
sim_plat.compile()
#autonetkit.update_http(anm, nidb)


{'_interfaces': {0: {'description': 'Loopback',
                     'id': 'lo:1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('192.168.0.4'),
                     'ipv4_subnet': IPNetwork('192.168.0.4/32'),
                     'type': 'loopback'},
                 1: {'description': 'to r2',
                     'id': 'eth0',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.0.10'),
                     'ipv4_cidr': IPNetwork('10.0.0.10/30'),
                     'ipv4_subnet': IPNetwork('10.0.0.8/30'),
                     'numeric_id': 0,
                     'ospf_cost': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True},
                 2: {'description': 'to r3',
                     'id': 'eth1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.0.14'),
                     'ipv4_cidr': IPNetwork('10.0.0.14/30'),
                     'ipv4_subnet': IPNetwork('10.0.0.12/30'),
                     'numeric_id': 1,
                     'ospf_cost': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True},
                 3: {'description': 'to r5',
                     'id': 'eth2',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.128.1'),
                     'ipv4_cidr': IPNetwork('10.0.128.1/30'),
                     'ipv4_subnet': IPNetwork('10.0.128.0/30'),
                     'numeric_id': 2,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True}},
 'asn': 1,
 'bgp': {'debug': True,
         'ebgp_neighbors': [{'asn': 2,
                             'dst_int_ip': IPAddress('10.0.128.2'),
                             'local_int_ip': IPAddress('10.0.128.1'),
                             'loopback': IPAddress('192.168.0.9'),
                             'neighbor': 'r5',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False}],
         'ibgp_neighbors': [{'asn': 1,
                             'loopback': IPAddress('192.168.0.1'),
                             'neighbor': 'r1',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'loopback': IPAddress('192.168.0.2'),
                             'neighbor': 'r2',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'loopback': IPAddress('192.168.0.3'),
                             'neighbor': 'r3',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False}],
         'ibgp_rr_clients': [],
         'ibgp_rr_parents': [],
         'ipv4_advertise_subnets': [IPNetwork('10.0.0.0/16')],
         'ipv6_advertise_subnets': []},
 'device_type': 'router',
 'host': 'localhost',
 'hostname': 'r4',
 'input_label': 'r4',
 'interfaces': [],
 'ip': {'use_ipv4': True, 'use_ipv6': False},
 'label': 'r4',
 'loopback': IPAddress('192.168.0.4'),
 'loopback_subnet': IPNetwork('192.168.0.4/32'),
 'mgmt_ip': IPAddress('172.16.0.1'),
 'ospf': [('ipv4_mpls_te', False), ('loopback_area', 0), ('process_id', 1), ('lo_interface', 'lo:1'), ('ospf_links', [[('network', IPNetwork('10.0.0.8/30')), ('area', None)], [('network', IPNetwork('10.0.0.12/30')), ('area', None)]]), ('passive_interfaces', [[('id', 'eth2')]])],
 'platform': 'netkit',
 'render': {'base': 'templates/quagga',
            'base_dst_folder': 'rendered/localhost/netkit/r4',
            'custom': {'abc': 'def.txt'},
            'dst_file': 'r4.conf',
            'dst_folder': 'rendered',
            'template': 'router.mako'},
 'ssh': {'use_key': True},
 'tap': {'id': 'eth3', 'ip': IPAddress('172.16.0.6')},
 'x': 324,
 'y': 162,
 'zebra': {'password': '1234', 'static_routes': []}}
{'_interfaces': {0: {'description': 'Loopback',
                     'id': 'lo:1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('192.168.0.9'),
                     'ipv4_subnet': IPNetwork('192.168.0.9/32'),
                     'type': 'loopback'},
                 1: {'description': 'to r4',
                     'id': 'eth0',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.128.2'),
                     'ipv4_cidr': IPNetwork('10.0.128.2/30'),
                     'ipv4_subnet': IPNetwork('10.0.128.0/30'),
                     'numeric_id': 0,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True},
                 2: {'description': 'to r3',
                     'id': 'eth1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.1.0.2'),
                     'ipv4_cidr': IPNetwork('10.1.0.2/16'),
                     'ipv4_subnet': IPNetwork('10.1.0.0/16'),
                     'numeric_id': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True}},
 'asn': 2,
 'bgp': {'debug': True,
         'ebgp_neighbors': [{'asn': 1,
                             'dst_int_ip': IPAddress('10.1.0.1'),
                             'local_int_ip': IPAddress('10.1.0.2'),
                             'loopback': IPAddress('192.168.0.3'),
                             'neighbor': 'r3',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'dst_int_ip': IPAddress('10.0.128.1'),
                             'local_int_ip': IPAddress('10.0.128.2'),
                             'loopback': IPAddress('192.168.0.4'),
                             'neighbor': 'r4',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False}],
         'ibgp_neighbors': [],
         'ibgp_rr_clients': [],
         'ibgp_rr_parents': [],
         'ipv4_advertise_subnets': [IPNetwork('10.1.0.0/16')],
         'ipv6_advertise_subnets': []},
 'device_type': 'router',
 'host': 'localhost',
 'hostname': 'r5',
 'input_label': 'r5',
 'interfaces': [],
 'ip': {'use_ipv4': True, 'use_ipv6': False},
 'label': 'r5',
 'loopback': IPAddress('192.168.0.9'),
 'loopback_subnet': IPNetwork('192.168.0.9/32'),
 'mgmt_ip': IPAddress('172.16.0.2'),
 'ospf': [('ipv4_mpls_te', False), ('loopback_area', 0), ('process_id', 1), ('lo_interface', 'lo:1'), ('ospf_links', []), ('passive_interfaces', [[('id', 'eth0')], [('id', 'eth1')]])],
 'platform': 'netkit',
 'render': {'base': 'templates/quagga',
            'base_dst_folder': 'rendered/localhost/netkit/r5',
            'custom': {'abc': 'def.txt'},
            'dst_file': 'r5.conf',
            'dst_folder': 'rendered',
            'template': 'router.mako'},
 'ssh': {'use_key': True},
 'tap': {'id': 'eth2', 'ip': IPAddress('172.16.0.7')},
 'x': 486,
 'y': 324,
 'zebra': {'password': '1234', 'static_routes': []}}
{'_interfaces': {0: {'description': 'Loopback',
                     'id': 'lo:1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('192.168.0.1'),
                     'ipv4_subnet': IPNetwork('192.168.0.1/32'),
                     'type': 'loopback'},
                 1: {'description': 'to r2',
                     'id': 'eth0',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.0.1'),
                     'ipv4_cidr': IPNetwork('10.0.0.1/30'),
                     'ipv4_subnet': IPNetwork('10.0.0.0/30'),
                     'numeric_id': 0,
                     'ospf_cost': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True},
                 2: {'description': 'to r3',
                     'id': 'eth1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.0.5'),
                     'ipv4_cidr': IPNetwork('10.0.0.5/30'),
                     'ipv4_subnet': IPNetwork('10.0.0.4/30'),
                     'numeric_id': 1,
                     'ospf_cost': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True}},
 'asn': 1,
 'bgp': {'debug': True,
         'ebgp_neighbors': [],
         'ibgp_neighbors': [{'asn': 1,
                             'loopback': IPAddress('192.168.0.2'),
                             'neighbor': 'r2',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'loopback': IPAddress('192.168.0.3'),
                             'neighbor': 'r3',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'loopback': IPAddress('192.168.0.4'),
                             'neighbor': 'r4',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False}],
         'ibgp_rr_clients': [],
         'ibgp_rr_parents': [],
         'ipv4_advertise_subnets': [IPNetwork('10.0.0.0/16')],
         'ipv6_advertise_subnets': []},
 'device_type': 'router',
 'host': 'localhost',
 'hostname': 'r1',
 'input_label': 'r1',
 'interfaces': [],
 'ip': {'use_ipv4': True, 'use_ipv6': False},
 'label': 'r1',
 'loopback': IPAddress('192.168.0.1'),
 'loopback_subnet': IPNetwork('192.168.0.1/32'),
 'mgmt_ip': IPAddress('172.16.0.3'),
 'ospf': [('ipv4_mpls_te', False), ('loopback_area', 0), ('process_id', 1), ('lo_interface', 'lo:1'), ('ospf_links', [[('network', IPNetwork('10.0.0.0/30')), ('area', None)], [('network', IPNetwork('10.0.0.4/30')), ('area', None)]]), ('passive_interfaces', [])],
 'platform': 'netkit',
 'render': {'base': 'templates/quagga',
            'base_dst_folder': 'rendered/localhost/netkit/r1',
            'custom': {'abc': 'def.txt'},
            'dst_file': 'r1.conf',
            'dst_folder': 'rendered',
            'template': 'router.mako'},
 'ssh': {'use_key': True},
 'tap': {'id': 'eth2', 'ip': IPAddress('172.16.0.3')},
 'x': 0,
 'y': 54,
 'zebra': {'password': '1234', 'static_routes': []}}
{'_interfaces': {0: {'description': 'Loopback',
                     'id': 'lo:1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('192.168.0.2'),
                     'ipv4_subnet': IPNetwork('192.168.0.2/32'),
                     'type': 'loopback'},
                 1: {'description': 'to r1',
                     'id': 'eth0',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.0.2'),
                     'ipv4_cidr': IPNetwork('10.0.0.2/30'),
                     'ipv4_subnet': IPNetwork('10.0.0.0/30'),
                     'numeric_id': 0,
                     'ospf_cost': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True},
                 2: {'description': 'to r4',
                     'id': 'eth1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.0.9'),
                     'ipv4_cidr': IPNetwork('10.0.0.9/30'),
                     'ipv4_subnet': IPNetwork('10.0.0.8/30'),
                     'numeric_id': 1,
                     'ospf_cost': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True}},
 'asn': 1,
 'bgp': {'debug': True,
         'ebgp_neighbors': [],
         'ibgp_neighbors': [{'asn': 1,
                             'loopback': IPAddress('192.168.0.1'),
                             'neighbor': 'r1',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'loopback': IPAddress('192.168.0.3'),
                             'neighbor': 'r3',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'loopback': IPAddress('192.168.0.4'),
                             'neighbor': 'r4',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False}],
         'ibgp_rr_clients': [],
         'ibgp_rr_parents': [],
         'ipv4_advertise_subnets': [IPNetwork('10.0.0.0/16')],
         'ipv6_advertise_subnets': []},
 'device_type': 'router',
 'host': 'localhost',
 'hostname': 'r2',
 'input_label': 'r2',
 'interfaces': [],
 'ip': {'use_ipv4': True, 'use_ipv6': False},
 'label': 'r2',
 'loopback': IPAddress('192.168.0.2'),
 'loopback_subnet': IPNetwork('192.168.0.2/32'),
 'mgmt_ip': IPAddress('172.16.0.4'),
 'ospf': [('ipv4_mpls_te', False), ('loopback_area', 0), ('process_id', 1), ('lo_interface', 'lo:1'), ('ospf_links', [[('network', IPNetwork('10.0.0.0/30')), ('area', None)], [('network', IPNetwork('10.0.0.8/30')), ('area', None)]]), ('passive_interfaces', [])],
 'platform': 'netkit',
 'render': {'base': 'templates/quagga',
            'base_dst_folder': 'rendered/localhost/netkit/r2',
            'custom': {'abc': 'def.txt'},
            'dst_file': 'r2.conf',
            'dst_folder': 'rendered',
            'template': 'router.mako'},
 'ssh': {'use_key': True},
 'tap': {'id': 'eth2', 'ip': IPAddress('172.16.0.4')},
 'x': 216,
 'y': 0,
 'zebra': {'password': '1234', 'static_routes': []}}
{'_interfaces': {0: {'description': 'Loopback',
                     'id': 'lo:1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('192.168.0.3'),
                     'ipv4_subnet': IPNetwork('192.168.0.3/32'),
                     'type': 'loopback'},
                 1: {'description': 'to r1',
                     'id': 'eth0',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.0.6'),
                     'ipv4_cidr': IPNetwork('10.0.0.6/30'),
                     'ipv4_subnet': IPNetwork('10.0.0.4/30'),
                     'numeric_id': 0,
                     'ospf_cost': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True},
                 2: {'description': 'to r4',
                     'id': 'eth1',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.0.0.13'),
                     'ipv4_cidr': IPNetwork('10.0.0.13/30'),
                     'ipv4_subnet': IPNetwork('10.0.0.12/30'),
                     'numeric_id': 1,
                     'ospf_cost': 1,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True},
                 3: {'description': 'to r5',
                     'id': 'eth2',
                     'id_brief': '',
                     'ipv4_address': IPAddress('10.1.0.1'),
                     'ipv4_cidr': IPNetwork('10.1.0.1/16'),
                     'ipv4_subnet': IPNetwork('10.1.0.0/16'),
                     'numeric_id': 2,
                     'physical': True,
                     'type': 'physical',
                     'use_ipv4': True}},
 'asn': 1,
 'bgp': {'debug': True,
         'ebgp_neighbors': [{'asn': 2,
                             'dst_int_ip': IPAddress('10.1.0.2'),
                             'local_int_ip': IPAddress('10.1.0.1'),
                             'loopback': IPAddress('192.168.0.9'),
                             'neighbor': 'r5',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False}],
         'ibgp_neighbors': [{'asn': 1,
                             'loopback': IPAddress('192.168.0.1'),
                             'neighbor': 'r1',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'loopback': IPAddress('192.168.0.2'),
                             'neighbor': 'r2',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False},
                            {'asn': 1,
                             'loopback': IPAddress('192.168.0.4'),
                             'neighbor': 'r4',
                             'update_source': None,
                             'use_ipv4': True,
                             'use_ipv6': False}],
         'ibgp_rr_clients': [],
         'ibgp_rr_parents': [],
         'ipv4_advertise_subnets': [IPNetwork('10.0.0.0/16')],
         'ipv6_advertise_subnets': []},
 'device_type': 'router',
 'host': 'localhost',
 'hostname': 'r3',
 'input_label': 'r3',
 'interfaces': [],
 'ip': {'use_ipv4': True, 'use_ipv6': False},
 'label': 'r3',
 'loopback': IPAddress('192.168.0.3'),
 'loopback_subnet': IPNetwork('192.168.0.3/32'),
 'mgmt_ip': IPAddress('172.16.0.5'),
 'ospf': [('ipv4_mpls_te', False), ('loopback_area', 0), ('process_id', 1), ('lo_interface', 'lo:1'), ('ospf_links', [[('network', IPNetwork('10.0.0.4/30')), ('area', None)], [('network', IPNetwork('10.0.0.12/30')), ('area', None)]]), ('passive_interfaces', [[('id', 'eth2')]])],
 'platform': 'netkit',
 'render': {'base': 'templates/quagga',
            'base_dst_folder': 'rendered/localhost/netkit/r3',
            'custom': {'abc': 'def.txt'},
            'dst_file': 'r3.conf',
            'dst_folder': 'rendered',
            'template': 'router.mako'},
 'ssh': {'use_key': True},
 'tap': {'id': 'eth3', 'ip': IPAddress('172.16.0.5')},
 'x': 162,
 'y': 270,
 'zebra': {'password': '1234', 'static_routes': []}}

In [20]:
import autonetkit.render
autonetkit.render.render(nidb)


INFO Rendering Network
INFO:ANK:Rendering Network

In [21]:
with open("rendered/lab.conf") as fh:
    print fh.read()


Topology rendered on 2014-01-13 00:58 by autonetkit_0.8.2
host: r4
host: r5
host: r1
host: r2
host: r3


In [22]:
with open("rendered/r1.conf") as fh:
    print fh.read()


Router rendered on 2014-01-13 00:58 by autonetkit_0.8.2
interface lo:1
    description Loopback
    ip address 192.168.0.1 netmask 255.255.255.255
interface eth0
    description to r2
    ip address 10.0.0.1 netmask 255.255.255.252
interface eth1
    description to r3
    ip address 10.0.0.5 netmask 255.255.255.252
!
router ospf 1
    network 10.0.0.0/30 area None
    network 10.0.0.4/30 area None
!
router bgp 1
  ! r2
  neighbor 192.168.0.2 remote-as 1
  neighbor 192.168.0.2 update-source 192.168.0.1
  neighbor 192.168.0.2 next-hop-self
  ! r3
  neighbor 192.168.0.3 remote-as 1
  neighbor 192.168.0.3 update-source 192.168.0.1
  neighbor 192.168.0.3 next-hop-self
  ! r4
  neighbor 192.168.0.4 remote-as 1
  neighbor 192.168.0.4 update-source 192.168.0.1
  neighbor 192.168.0.4 next-hop-self
!
!    


In [23]:
with open("rendered/r5.conf") as fh:
    print fh.read()


Router rendered on 2014-01-13 00:58 by autonetkit_0.8.2
interface lo:1
    description Loopback
    ip address 192.168.0.9 netmask 255.255.255.255
interface eth0
    description to r4
    ip address 10.0.128.2 netmask 255.255.255.252
interface eth1
    description to r3
    ip address 10.1.0.2 netmask 255.255.0.0
!
router ospf 1
!
router bgp 2
!
  ! r3
  neighbor 10.1.0.1 remote-as 1
  neighbor 10.1.0.1 update-source 10.1.0.2
  ! r4
  neighbor 10.0.128.1 remote-as 1
  neighbor 10.0.128.1 update-source 10.0.128.2
!