Skip to content

Commit

Permalink
Merge pull request #264 from sk2/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
sk2 committed Nov 27, 2014
2 parents f7e8c03 + 51f1452 commit fdfff7e
Show file tree
Hide file tree
Showing 23 changed files with 532 additions and 89 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.10.12
current_version = 0.11.0
files = setup.py
commit = True
tag = True
Expand Down
50 changes: 50 additions & 0 deletions autonetkit/ank.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,3 +767,53 @@ def boundary_nodes(nm_graph, nodes):
assert all(n in nbunch for n in internal_nodes) # check internal

return wrap_nodes(nm_graph, internal_nodes)

def shallow_copy_nx_graph(nx_graph):
"""Convenience wrapper for nx shallow copy
>>> import networkx
>>> G = nx.Graph()
>>> H = shallow_copy_nx_graph(G)
>>> isinstance(H, nx.Graph)
True
>>> isinstance(H, nx.DiGraph)
False
>>> isinstance(H, nx.MultiGraph)
False
>>> isinstance(H, nx.MultiDiGraph)
False
>>> G = nx.DiGraph()
>>> H = shallow_copy_nx_graph(G)
>>> isinstance(H, nx.DiGraph)
True
>>> G = nx.MultiGraph()
>>> H = shallow_copy_nx_graph(G)
>>> isinstance(H, nx.MultiGraph)
True
>>> G = nx.MultiDiGraph()
>>> H = shallow_copy_nx_graph(G)
>>> isinstance(H, nx.MultiDiGraph)
True
"""
import networkx
directed = nx_graph.is_directed()
multi = nx_graph.is_multigraph()

if directed:
if multi:
return nx.MultiDiGraph(nx_graph)
else:
return nx.DiGraph(nx_graph)
else:
if multi:
return nx.MultiGraph(nx_graph)
else:
return nx.Graph(nx_graph)




17 changes: 10 additions & 7 deletions autonetkit/ank_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import networkx as nx
from networkx.readwrite import json_graph
from autonetkit.render2 import NodeRender, PlatformRender
from autonetkit.ank import shallow_copy_nx_graph


class AnkEncoder(json.JSONEncoder):
Expand Down Expand Up @@ -277,7 +278,15 @@ def jsonify_anm_with_graphics(anm, nidb=None):
key=lambda x: nodes_by_layer.get(x, 0))

for overlay_id in overlay_ids:
nm_graph = anm[overlay_id]._graph.copy()
try:
#make a shallow copy
# input_graph = anm[overlay_id]._graph
# nm_graph = shallow_copy_nx_graph(input_graph)
nm_graph = anm[overlay_id]._graph.copy()
except Exception, e:
log.warning("Unable to copy overlay %s: %s", overlay_id, e)
continue

if overlay_id == "_dependencies":
# convert to undirected for visual clarify
nm_graph = nx.Graph(nm_graph)
Expand Down Expand Up @@ -335,12 +344,6 @@ def jsonify_anm_with_graphics(anm, nidb=None):
# store on graph
nm_graph.node[node] = node_data

if nm_graph.is_multigraph():
for u, v, k in nm_graph.edges(keys=True):
# Store key: nx node_link_data ignores it
#anm_graph[u][v][k]['_key'] = k
pass # is this needed? as key itself holds no value?

try:
del nm_graph.node[node]['id']
except KeyError:
Expand Down
1 change: 1 addition & 0 deletions autonetkit/anm/ank_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class AnkElement(object):

#TODO: put this into parent __init__?
def init_logging(self, my_type):
return
try:
self_id = str(self)
except Exception, e:
Expand Down
3 changes: 3 additions & 0 deletions autonetkit/anm/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ def allocate_input_interfaces(self):
self.edges()):
log.debug("Input interfaces allocated")
return # interfaces allocated
elif self.data.interfaces_allocated == True:
# explicitly flagged as allocated
return
else:
log.info('Automatically assigning input interfaces')

Expand Down
3 changes: 3 additions & 0 deletions autonetkit/anm/graph_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ def _graph(self):

return self.anm.overlay_nx_graphs[self.overlay_id]

def __contains__(self, key):
return key in self._graph.graph

def __getattr__(self, key):
return self._graph.graph.get(key)

Expand Down
9 changes: 9 additions & 0 deletions autonetkit/anm/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,15 @@ def is_router(self):
return self.device_type == 'router' or self['phy'].device_type \
== 'router'

def is_hub(self):
"""Either from this graph or the physical graph
"""
#self.log_info("add int")

return self.device_type == 'hub' or self['phy'].device_type \
== 'hub'

def is_device_type(self, device_type):
"""Generic user-defined cross-overlay search for device_type
either from this graph or the physical graph"""
Expand Down
6 changes: 5 additions & 1 deletion autonetkit/build_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def check_server_asns(anm):
g_phy = anm['phy']

for server in g_phy.servers():
#TODO: remove now have external_connector device_type?
if server.device_subtype in ("SNAT", "FLAT"):
continue # Don't warn on ASN for NAT elements
l3_neighbors = list(server['layer3'].neighbors())
Expand Down Expand Up @@ -161,9 +162,11 @@ def apply_design_rules(anm):
cisco_build_network.post_phy(anm)

g_phy = anm['phy']
from autonetkit.design.osi_layers import build_layer2, build_layer3
from autonetkit.design.osi_layers import build_layer1, build_layer2, build_layer3
# log.info("Building layer2")
build_layer1(anm)
build_layer2(anm)
# autonetkit.update_http(anm)

# log.info("Building layer3")
build_layer3(anm)
Expand Down Expand Up @@ -295,6 +298,7 @@ def build_phy(anm):
if specified_id:
interface.specified_id = specified_id # map across

#TODO: tidy this code up
for node in g_phy:
for interface in node:
remote_edges = interface.edges()
Expand Down
60 changes: 60 additions & 0 deletions autonetkit/compilers/device/cisco.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ def compile(self, node):
node.isis.use_ipv4 = phy_node.use_ipv4
node.isis.use_ipv6 = phy_node.use_ipv6

if node in self.anm['rip']:
node.add_stanza("rip")
node.rip.use_ipv4 = phy_node.use_ipv4
node.rip.use_ipv6 = phy_node.use_ipv6

super(IosBaseCompiler, self).compile(node)
if node in self.anm['isis']:
self.isis(node)
Expand Down Expand Up @@ -339,6 +344,25 @@ def vrf(self, node):
node.mpls.enabled = True
node.mpls.router_id = node.loopback_zero.id

def rip(self, node):
#Inheriting from base compiler. Adding in interface stanza.
super(IosBaseCompiler, self).rip(node)
for interface in node.physical_interfaces():
phy_int = self.anm['phy'].interface(interface)

rip_int = phy_int['rip']
if rip_int and rip_int.is_bound:
if interface.exclude_igp:
continue

interface.rip = {
'cost': rip_int.cost,
'area': rip_int.area,
'process_id': node.rip.process_id,
'use_ipv4': node.ip.use_ipv4,
'use_ipv6': node.ip.use_ipv6,
}

def ospf(self, node):
super(IosBaseCompiler, self).ospf(node)
for interface in node.physical_interfaces():
Expand Down Expand Up @@ -475,6 +499,9 @@ def compile(self, node):
node.exclude_phy_int_auto_speed_duplex = True
node.no_service_config = True

def rip(self, node):
super(IosClassicCompiler, self).rip(node)

def ospf(self, node):
super(IosClassicCompiler, self).ospf(node)
loopback_zero = node.loopback_zero
Expand Down Expand Up @@ -722,6 +749,32 @@ def mpls_te(self, node):
node.add_stanza("rsvp")
node.rsvp.interfaces = rsvp_interfaces
node.mpls.te_interfaces = mpls_te_interfaces

def rip(self, node):
super(IosXrCompiler, self).rip(node)

g_rip = self.anm['rip']
ipv4_interfaces = []

for interface in node.physical_interfaces():
if interface.exclude_igp:
continue # discontinue configuring IGP for this interface

rip_int = g_rip.interface(interface)
if rip_int and rip_int.is_bound:
data = {'id': interface.id, 'passive': False}
stanza = ConfigStanza(**data)
if node.rip.use_ipv4:
ipv4_interfaces.append(stanza)

loopback_zero = node.loopback_zero
data = {'id': node.loopback_zero.id, 'passive': True}
stanza = ConfigStanza(**data)
if node.rip.use_ipv4:
ipv4_interfaces.append(stanza)


node.rip.ipv4_interfaces = ipv4_interfaces

def ospf(self, node):
super(IosXrCompiler, self).ospf(node)
Expand Down Expand Up @@ -823,6 +876,13 @@ def interfaces(self, node):

super(NxOsCompiler, self).interfaces(node)

def rip(self, node):
super(NxOsCompiler, self).rip(node)
loopback_zero = node.loopback_zero
loopback_zero.rip = {'use_ipv4': node.ip.use_ipv4,
'process_id': node.rip.process_id}


def ospf(self, node):
super(NxOsCompiler, self).ospf(node)
loopback_zero = node.loopback_zero
Expand Down
55 changes: 41 additions & 14 deletions autonetkit/compilers/device/router_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ def compile(self, node):
self.isis(node)
if self.anm.has_overlay('eigrp') and node in self.anm['eigrp']:
self.eigrp(node)
###self.rip(node)
if self.anm.has_overlay('rip') and node in self.anm['rip']:
self.rip(node)
# TODO: drop bgp overlay
bgp_overlays = ["bgp", "ebgp_v4", "ibgp_v4", "ebgp_v6", "ibgp_v6"]
use_bgp = False
Expand Down Expand Up @@ -421,31 +424,28 @@ def bgp(self, node):

return

def eigrp(self, node):

g_eigrp = self.anm['eigrp']
def rip(self, node):
g_rip = self.anm['rip']
g_ipv4 = self.anm['ipv4']
eigrp_node = self.anm['eigrp'].node(node)
node.eigrp.process_id = eigrp_node.process_id
node.eigrp.custom_config = eigrp_node.custom_config
rip_node = self.anm['rip'].node(node)
node.rip.process_id = rip_node.process_id
node.rip.custom_config = rip_node.custom_config

ipv4_networks = set()
for interface in node.physical_interfaces():
if interface.exclude_igp:
continue # don't configure IGP for this interface
continue # discontinue configuring IGP for this interface.
ipv4_int = g_ipv4.interface(interface)
eigrp_int = g_eigrp.interface(interface)
if not eigrp_int.is_bound:
continue # not an EIGRP interface
rip_int = g_rip.interface(interface)
if not rip_int.is_bound:
continue # not an rip interface
network = ipv4_int.subnet
if eigrp_int and eigrp_int.is_bound and interface.use_ipv4:
if rip_int and rip_int.is_bound and interface.use_ipv4:
ipv4_networks.add(network)

# Loopback zero subnet

ipv4_networks.add(node.loopback_zero.ipv4_cidr)
node.rip.ipv4_networks = sorted(list(ipv4_networks))

node.eigrp.ipv4_networks = sorted(list(ipv4_networks))

def isis(self, node):
g_isis = self.anm['isis']
Expand Down Expand Up @@ -490,3 +490,30 @@ def isis(self, node):
'use_ipv6': node.ip.use_ipv6}

# TODO: add wrapper for this

def eigrp(self, node):

g_eigrp = self.anm['eigrp']
g_ipv4 = self.anm['ipv4']
eigrp_node = self.anm['eigrp'].node(node)
node.eigrp.process_id = eigrp_node.process_id
node.eigrp.custom_config = eigrp_node.custom_config

ipv4_networks = set()
for interface in node.physical_interfaces():
if interface.exclude_igp:
continue # don't configure IGP for this interface
ipv4_int = g_ipv4.interface(interface)
eigrp_int = g_eigrp.interface(interface)
if not eigrp_int.is_bound:
continue # not an EIGRP interface
network = ipv4_int.subnet
if eigrp_int and eigrp_int.is_bound and interface.use_ipv4:
ipv4_networks.add(network)

# Loopback zero subnet


ipv4_networks.add(node.loopback_zero.ipv4_cidr)

node.eigrp.ipv4_networks = sorted(list(ipv4_networks))
7 changes: 7 additions & 0 deletions autonetkit/compilers/platform/cisco.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ def compile_devices(self):
DmNode = self.nidb.node(phy_node)
DmNode.indices = phy_node.indices

managed_switches = [n for n in g_phy.switches()
if n.host == self.host
and n.device_subtype == "managed"]
for phy_node in managed_switches:
DmNode = self.nidb.node(phy_node)
DmNode.indices = phy_node.indices

for phy_node in g_phy.l3devices(host=self.host):
loopback_ids = self.loopback_interface_ids()
# allocate loopbacks to routes (same for all ios variants)
Expand Down
2 changes: 1 addition & 1 deletion autonetkit/console_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def main(options):
grid=options.grid, **build_options)
except Exception, err:
log.error(
"Error generating network configurations: %s. More information may be available in the debug log." % err)
"Error generating network configurations: %s" % err)
log.debug("Error generating network configurations", exc_info=True)
if settings['General']['stack_trace']:
print traceback.print_exc()
Expand Down
Loading

0 comments on commit fdfff7e

Please sign in to comment.