def getAllRings(graph, isMultigraph): """ Parameters: graph -> networkx graph or multigraph object, isMultigraph -> True if graph is multigraph else false Returns list of list of edges forming cycles in the graph. """ if isMultigraph: multigraph, graph = graph, nx.Graph(graph) all_cycle_edge_list = [] Debuglogger.info("Getting cycle basis") cycle_basis_list = getCycleBasis(graph) # get cycle basis of given graph Userlogger.info('\nGetting all the rings from physical topology') for i in range(1,len(cycle_basis_list)+1): # form combinations of cycle basis Debuglogger.debug("Getting combinations of basis cycle picking "+str(i)+" items") for combination in combinations(cycle_basis_list,i): if combination: Debuglogger.debug("combination exists") edge_set = {} for basis in combination: # find symmetric difference of edge_set = set(basis).symmetric_difference(edge_set)# members of each combination ring = nx.Graph() ring.add_edges_from(list(edge_set)) if isCycle(ring): #if the member is a connected cycle Debuglogger.debug("Is a connected cycle") all_cycle_edge_list.append(list(edge_set)) # add to list of all cycles Debuglogger.info("Ring "+str(len(all_cycle_edge_list))+" "+str(all_cycle_edge_list[-1])) Userlogger.info("Ring "+str(len(all_cycle_edge_list))+" "+str(all_cycle_edge_list[-1])) if isMultigraph: return getRingsMultigraph(multigraph, all_cycle_edge_list) return all_cycle_edge_list
def drawTopology(topology,isMultigraph,saveas): """ drawTopology() method takes networkx object of the network, filename of the image to create and creates image of the network with a given filename. """ Debuglogger.info("Drawing graph with a given networkxobject")# G = pydot.Dot(graph_type='graph', dpi=300 , splines = "curved") G.set_node_defaults(style="filled", fillcolor="grey",fontsize=7.0) G.set_layout("circo") G.set_edge_defaults(fontsize=7.0) for edge in list(set(topology.edges())): node1=edge[0] node2=edge[1] if isMultigraph: for ed_info in topology[node1][node2]: if topology[node1][node2][ed_info]['link_type']=='Gig': edge_style = 'bold' elif topology[node1][node2][ed_info]['link_type'] == 'Fas': edge_style = 'dotted' G.add_edge(pydot.Edge(node1,node2,style=edge_style,label=topology[node1][node2][ed_info]['wt'])) else: #print saveas if topology[node1][node2]['link_type']=='Gig': edge_style = 'bold' elif topology[node1][node2]['link_type'] == 'Fas': edge_style = 'dotted' G.add_edge(pydot.Edge(node1,node2,style=edge_style,label=topology[node1][node2]['wt'])) G.write_png(saveas)
def makeGraph(edges_info): """ makeGraph() method takes edges_info as input and returns a networkx object of the network. edges_info is a list with entries being the edges in the network. Edges are entered as two switchname+IPs+Ports and corresponding intefaces and type of link. """ Debuglogger.info("Making a graph object with a given Edge list") graph = nx.Graph() multigraph = nx.MultiGraph() for edge in edges_info: info = edge.split(' ') node1 = info[0] node2 = info[1] port = " ".join(info[2:-1]) link_type = info[-1] if node1 not in graph: graph.add_node(node1,node_port=[]) multigraph.add_node(node1,node_port=[]) graph.node[node1]['node_port'].append(info[2]) multigraph.node[node1]['node_port'].append(info[2]) if node2 not in graph: graph.add_node(node2,node_port=[]) multigraph.add_node(node2,node_port=[]) graph.node[node2]['node_port'].append(info[3]) multigraph.node[node2]['node_port'].append(info[3]) multigraph.add_edge(node1,node2, wt=port, link_type=link_type) graph.add_edge(node1,node2, wt=port, link_type=link_type) if len(multigraph.edges())>len(graph.edges()): return multigraph,True return graph,False
def eList_Modify(): """ eList_Modify() modifies the EdgeList such as that instead of switchname it replaces the switchname with switchname+IP+Port. """ Debuglogger.info("Modifying the Edge List in Network")# for switch_info in Network_topology.SwitchList.keys(): switch_name= switch_info.split('\n')[0] for i in range(0,len(Network_topology.EdgeList)): Network_topology.EdgeList[i]=Network_topology.EdgeList[i].replace(switch_name,switch_info)
def isCycle(graph): """ This function takes a networkx graph object as input and returns True if the graph is a cycle Note: A graph is a cycle iff degree of every node is two and the graph is connected. """ if graph: degree_hist = nx.degree_histogram(graph) # get frequency of degree of all nodes if degree_hist[2] == len(graph.nodes()) and nx.is_connected(graph): # if all nodes have degree = 2 => cycle Debuglogger.debug("Is a cycle") return True Debuglogger.debug("Is not a cycle") return False
def findname(self): """ findname() finds the name of switch from cdp data. """ Debuglogger.info("Finding name through cdp data") fout=open('tempLog.txt','r') lines=fout.readlines() for line in lines: if '>' in line: break self.SwitchName=line[0:line.index('>')] fout.close()
def getCycleBasis(graph): """ Input: networkx simple graph Returns list of graph objects that form cycle basis of the input graph """ Debuglogger.info("In getCycleBasis") cycle_basis_list = [] # list of list of edges of each cycle basis for cycle in nx.cycle_basis(graph): Debuglogger.debug("cycle basis ->"+str(cycle)) cycle_graph = nx.Graph() cycle_graph.add_cycle(cycle) cycle_basis_list.append(cycle_graph.edges()) return cycle_basis_list
def cdpread(self): """ cdpread() method runs cdp command through commandExecute() defined in RunCommands module to find the neighbours. It calls findname() and addedge() to find the name of switch and finding edges corresponding to that switch. """ Debuglogger.info("In network topology") run.Switch_commands.commandExecute(self.host,self.port,'exec','show cdp ne') self.findname() Userlogger.info('\nLogged into : '+self.SwitchName+' '+self.host+' '+self.port) Userlogger.info(self.SwitchName+'is connected to :') Network_topology.SwitchList[self.SwitchName+'\n'+self.host+'\n'+self.port]=[] self.addedge() Userlogger.info('\n')
def switch_exec(ip,port): """ makes the switch in exec mode instead of config mode. """ Debuglogger.info("In switch_exec function") Debuglogger.info("makes switch ("+ip+' '+port+") in exec mode") Userlogger.info("makes switch ("+ip+' '+port+") in exec mode") child= pexpect.spawn('telnet '+ip+' '+port) child.expect('Escape.*') child.sendcontrol('m') child.expect('#') child.sendline('end') child.expect('#') child.sendline('quit') child.expect(' ') child.sendcontrol('m') child.expect('>')
def showrepp(graph): " shows the rep topology" node=graph.nodes()[0] node_data=node.split('\n') Debuglogger.info('\nin show repp function') Userlogger.info('\nshowing the rep configuration') while 1: try: run.Switch_commands.commandExecute(node_data[1],node_data[2],'exec','show rep topology') templog=open('tempLog.txt','r') lines=templog.readlines() i=5 while i<len(lines): print lines[i] i+=1 templog.close() break except: pass
def clearline(ip,port): """ clear the line of the given switch with ip and port """ Debuglogger.info("In Clearline function") Debuglogger.info("Clear the line of switch with "+ip+' '+port) Userlogger.info("Clear the line of switch with "+ip+' '+port) child= pexpect.spawn('telnet '+ip) child.expect('Password:'******'lab') child.expect('>') child.sendline('en') child.expect('Password:'******'lab') child.expect('#') child.sendline('clear line '+str(int(port)%100)) child.sendcontrol('m') child.expect('#') child.close() print "line is cleared"
def addedge(self): """ addedge() finds the edge from the cdp data and calls eList() to add the edge entry (two switch name and corresponding interfaces and type of link) in EdgeList. """ Debuglogger.info("Finding Edges") fCDP=open('tempLog.txt','r') lines=fCDP.readlines() i=0 #to get to that line which has switch information for line in lines: if "Device ID" in lines[i]: i+=1 break i+=1 while i< len(lines): currentline_info=lines[i].split() Ln=len(currentline_info) if Ln==0: break #this is to include if switch name is too long then it interface information comes to next line elif Ln==1: i=i+1 nextline_info=lines[i].split() destSwitch=currentline_info[0] source_interface=nextline_info[0]+nextline_info[1] dest_interface=nextline_info[-2]+nextline_info[-1] i=i+1 else: destSwitch=currentline_info[0] source_interface=currentline_info[1]+currentline_info[2] dest_interface=currentline_info[-2]+currentline_info[-1] i=i+1 Network_topology.SwitchList[self.SwitchName+'\n'+self.host+'\n'+self.port].append(source_interface+' '+dest_interface) self.eList(destSwitch, source_interface, dest_interface) Userlogger.info(destSwitch) fCDP.close()
def formatCycleEdgeList(graph, isMultigraph, all_cycle_edge_list_tuple, SwitchList): """ Input -> graph object, bool whether multigraph or not, list of list of edges forming a cycle, dictionary port-port mappin gfor each node Returns list of list of edges forming cycle with attribute information """ Debuglogger.info("In formatCycleEdgeList - isMultigraph: "+str(isMultigraph)) all_cycle_edge_list_str = [] for ring in all_cycle_edge_list_tuple: cycle_str = [] for edge in ring: node1 = edge[0] node2 = edge[1] if not isMultigraph: edge_dict = graph[node1][node2] else: edge_dict = graph[node1][node2][edge[-1]] if edge_dict['wt'] in SwitchList[node1]: edge = (node1, node2, edge_dict['wt'], edge_dict['link_type']) else: edge = (node2, node1, edge_dict['wt'], edge_dict['link_type']) edge = " ".join(edge) #Debuglogger.debug(edge) cycle_str.append(edge) Debuglogger.debug(cycle_str) all_cycle_edge_list_str.append(cycle_str) return all_cycle_edge_list_str
def getRingsMultigraph(multigraph, all_cycle_edge_list): """ Input -> multigraph object, list of cycles or rings got from simple graph Returns list of list of edges of a ring. Edge is represented as (node1.node2,edge_id) """ Debuglogger.info("In getRingsMultigraph") all_cycle_edge_list_multi = [] for ring in all_cycle_edge_list: Debuglogger.debug("Ring:"+str(ring)) cycle = [] multi_edge_list = [] edge_index = [] for edge in ring: Debuglogger.debug("Edge:"+str(edge)) node1 = edge[0] node2 = edge[1] if len(multigraph[node1][node2])>1: Debuglogger.info("this ia a multi edge") single_multi_edge = [] for edge_id in multigraph[node1][node2].keys(): single_multi_edge.append((node1, node2, edge_id)) edge_new = single_multi_edge[0] multi_edge_list.append(single_multi_edge) edge_index.append(ring.index(edge)) else: edge_new = edge + (0,) cycle.append(edge_new) all_cycle_edge_list_multi.append(cycle) Debuglogger.debug("multi_edge_list:"+str(multi_edge_list)) if multi_edge_list: for combination in product(*multi_edge_list): for i in range(len(combination)): idx = edge_index[i] temp = cycle[:idx]+[combination[i]] if i<len(cycle): temp+=cycle[idx+1:] cycle = temp #print cycle if temp not in all_cycle_edge_list_multi: all_cycle_edge_list_multi.append(temp) Userlogger.info("Ring "+str(len(all_cycle_edge_list_multi))+" "+str(temp)) Debuglogger.info("Ring "+str(len(all_cycle_edge_list_multi))+" "+str(temp)) return all_cycle_edge_list_multi