def generate_graph_rep_and_augment(): # Config files -> batfish -> emulation # first, let's get the networkx graph G = nx.Graph() G_layer_2 = nx.Graph() G_layer_3 = nx.Graph() color_map = [] device_dataframe = bfq.nodeProperties().answer().frame() add_devices_to_graphs(device_dataframe, G, G_layer_2, G_layer_3, color_map) interface_dataframe = bfq.interfaceProperties().answer().frame() add_interfaces_to_graphs(interface_dataframe, G, G_layer_2, G_layer_3, color_map) edge_dataframe = bfq.edges().answer().frame() edges_layer1_dataframe = bfq.layer1Edges().answer().frame() edge_interfaces = set() connected_interfaces = add_edges_to_graphs( edge_dataframe, G, G_layer_2, G_layer_3, color_map, edge_interfaces, edges_layer1_dataframe, ) for connected_interface in connected_interfaces: if str(connected_interface) in G_layer_2.nodes(): G_layer_2.remove_node(str(connected_interface)) return G, G_layer_2, G_layer_3, color_map
def resolve(self): data = {} result = bfq.interfaceProperties( nodes=self.node_spec, interfaces=self.interface_spec, properties=self.interface_property).answer().frame() for node in result.Interface.values: data[node.hostname] = self.commands return data
def _get_isis_enabled_links(self, description='core-link'): isis_enabled_links = list() interfaces = bfq.interfaceProperties().answer() for int in interfaces.rows: if int.get('Description') != None and description in int.get( 'Description'): isis_enabled_links.append({ 'hostname': int.get('Interface').get('hostname'), 'interface': int.get('Interface').get('interface') }) return isis_enabled_links
def get_internal_interfaces(self) -> Set[str]: edge = self.build_directed_graph() pending_nodes = self.affected_nodes.copy() affected_interfaces = [] while len(pending_nodes) > 0: node = pending_nodes[0] pending_nodes = pending_nodes[1:] results = bfq.interfaceProperties(nodes=node).answer(snapshot=self.snapshot).frame() for idx, result in results.iterrows(): affected_interfaces.append(interface_to_str(result.Interface)) if "border" in node: continue if node not in edge: continue for parent in edge[node]: pending_nodes.append(parent) return set(affected_interfaces)
def deactivate_po_members(bf_snapshot_base, bf_snapshot_fail): po_members = list( bfq.interfaceProperties( nodes=PORT_CHANNEL_MEMBER_SCOPE, properties="Channel_Group").answer().frame().dropna().Interface) for po_member in po_members: print( f"[*] Deactivating port-channel member: [magenta bold]{po_member}[/magenta bold]", end=" ", ) bf_fork_snapshot( base_name=bf_snapshot_base, name=bf_snapshot_fail, deactivate_interfaces=[po_member], overwrite=True, ) pprint_results( get_differential_reachability(bf_snapshot_base, bf_snapshot_fail))
def build_topology(base: str, config_path: str, reachable_nodes: Set[str], sensitive_nodes: Set[str]) -> Topology: reachable_interfaces = get_reachable_interfaces_endnodes( base, config_path, reachable_nodes) interfaces = set() results = bfq.interfaceProperties().answer().frame() for _, result in results.iterrows(): interfaces.add(interface_to_str(result.Interface)) links = [] results = bfq.layer3Edges().answer(snapshot=base).frame() for _, result in results.iterrows(): i1 = result.Interface i1_str = interface_to_str(i1) i2 = result.Remote_Interface i2_str = interface_to_str(i2) type = "accessible" if i1.hostname in sensitive_nodes or i2.hostname in sensitive_nodes: type = "sensitive" if i1_str not in reachable_interfaces or i2_str not in reachable_interfaces: type = "protected" links.append((i1_str, i2_str, type)) return Topology(reachable_interfaces, interfaces.difference(reachable_interfaces), links)
def interfaces_from_snapshot(snapshot: str, nodes: str = None) -> Set[str]: cache_path = os.path.join(snapshot, "interface_from_snapshot.json") found = False if os.path.exists(cache_path): found = True caches = json.load(open(cache_path)) else: bf_init_snapshot(snapshot, "interface_from_snapshot", overwrite=True) caches = {} if len(caches) == 0: results = bfq.interfaceProperties().answer( snapshot="interface_from_snapshot").frame() for _, result in results.iterrows(): if result.Interface.hostname not in caches: caches[result.Interface.hostname] = [] caches[result.Interface.hostname].append( interface_to_str(result.Interface)) json.dump(caches, open(cache_path, "w")) if not found: bf_delete_snapshot("interface_from_snapshot") if nodes: return set(caches[nodes]) else: return set([y for x in caches.values() for y in x])
BATFISH_SERVICE_IP = "batfish" bf_session.host = BATFISH_SERVICE_IP load_questions() bf_init_snapshot(SNAPSHOT_PATH, name=SNAPSHOT_NAME, overwrite=True) spine_lo0 = ["8.8.8.8/32", "9.9.9.9/32"] devices = [ "base_lab_Spine1", "base_lab_Spine2", "base_lab_Leaf1", "base_lab_Leaf2", "base_lab_Leaf3", "base_lab_Leaf4" ] #Check to see if all interfaces will come up when this is deployed print("******** Showing all of the Interfaces which are connected ********") int_check = bfq.interfaceProperties(properties="Active").answer() print(int_check) #Check to show all of the edge connected services print("******** Showing all of the edge connected servivces ********") edge_services = bfq.bgpEdges().answer().frame() print(edge_services) #Check for peerings peerings print("******** Showing BGP peering sessions for all nodes ********") bgp_peers = bfq.bgpSessionStatus(nodes='/Leaf/').answer().frame() print(bgp_peers) #Make sure that we can achieve multipathing to the spines loopbacks print( "********** Checking leaf switches for loopback connectivity to spines ********"
def analyse_network(report_dir): """ This function runs batfish questions and captures the query results into a spread sheet. :param report_dir: defines the directory in which the analysis report gets saved """ # Captures the status of the configurations that were Parsed. parse_status = bfq.fileParseStatus().answer().frame() # Batfish question to extract node properties print(Fore.YELLOW + " ==> GETTING NODE PROPERTIES") np = bfq.nodeProperties().answer().frame() # Batfish question to extract interface properties print(Fore.YELLOW + " ==> GETTING INTERFACE PROPERTIES") interface = bfq.interfaceProperties().answer().frame() # Batfish question to extract VLAN properties print(Fore.YELLOW + " ==> GETTING VLAN PROPERTIES") vlan_prop = bfq.switchedVlanProperties().answer().frame() # Batfish question to extract IP Owners print(Fore.YELLOW + " ==> GETTING IPOWNERS") ip_owners = bfq.ipOwners().answer().frame() # Batfish question to extract L3 edges print(Fore.YELLOW + " ==> GETTING L3 EDGES") l3edge = bfq.layer3Edges().answer().frame() # Batfish question to extract MPLAG properties print(Fore.YELLOW + " ==> GETTING MLAG PROPERTIES") mlag = bfq.mlagProperties().answer().frame() # Batfish question to extract OSPF configuration print(Fore.YELLOW + " ==> GETTING OSPF CONFIGURATION") ospf_config = bfq.ospfProcessConfiguration().answer().frame() # Batfish question to extract OSPF area configuration print(Fore.YELLOW + " ==> GETTING OSPF AREA CONFIGURATION") ospf_area_config = bfq.ospfAreaConfiguration().answer().frame() # Batfish question to extract OSPF interface configuration print(Fore.YELLOW + " ==> GETTING OSPF INTERFACE CONFIGURATION") ospf_interface = bfq.ospfInterfaceConfiguration().answer().frame() # Batfish question to extract OSPF Session compatability print(Fore.YELLOW + " ==> GETTING OSPF SESSION COMPATABILITY") ospf_session = bfq.ospfSessionCompatibility().answer().frame() # Batfish question to extract BGP configuration print(Fore.YELLOW + " ==> GETTING BGP CONFIGURATION") bgp_config = bfq.bgpProcessConfiguration().answer().frame() # Batfish question to extract BGP peer configuration print(Fore.YELLOW + " ==> GETTING BGP PEER CONFIGURATION") bgp_peer_config = bfq.bgpPeerConfiguration().answer().frame() # Batfish question to extract BGP session compatibility print(Fore.YELLOW + " ==> GETTING BGP SESSION COMPATIBILITY") bgp_session = bfq.bgpSessionStatus().answer().frame() # Batfish question to extract routing table print(Fore.YELLOW + " ==> GETTING ROUTE TABLE") routing = bfq.routes().answer().frame() # Batfish question to extract F5 VIP configuration print(Fore.YELLOW + " ==> GETTING F5 VIP CONFIGURATION") f5_vip = bfq.f5BigipVipConfiguration().answer().frame() # Batfish question to extract Named Structures print(Fore.YELLOW + " ==> GETTING NAMED STRUCTURES") named_structure = bfq.namedStructures().answer().frame() # Batfish question to extract Structure deginitions print(Fore.YELLOW + " ==> GETTING STRUCTURE DEFINITIONS") def_structure = bfq.definedStructures().answer().frame() # Batfish question to extract referenced structures print(Fore.YELLOW + " ==> GETTING REFERENCED STRUCTURES") ref_structure = bfq.referencedStructures().answer().frame() # Batfish question to extract undefined references print(Fore.YELLOW + " ==> GETTING UNDEFINED STRUCTURE REFERENCES") undefined_references = bfq.undefinedReferences().answer().frame() # Batfish question to extract used structures print(Fore.YELLOW + " ==> GETTING UNUSED STRUCTURES") unused_structure = bfq.unusedStructures().answer().frame() # Setting the path and file name were the analysis report will be saved analysis_report_file = report_dir + "/" + NETWORK_NAME + "_analysis_report.xlsx" print(Fore.YELLOW + " ==> GENERATING REPORT") # Writes previously computed configuration analysis into a excel file with pd.ExcelWriter(analysis_report_file) as f: parse_status.to_excel(f, sheet_name="parse_satus", engine="xlsxwriter") np.to_excel(f, sheet_name="node_properties", engine="xlsxwriter") interface.to_excel(f, sheet_name="interface_properties", engine="xlsxwriter") vlan_prop.to_excel(f, sheet_name="vlan_properties", engine="xlsxwriter") ip_owners.to_excel(f, sheet_name="IPOwners", engine="xlsxwriter") l3edge.to_excel(f, sheet_name="l3edges", engine="xlsxwriter") mlag.to_excel(f, sheet_name="mlag", engine="xlsxwriter") ospf_session.to_excel(f, sheet_name="ospf_session", engine="xlsxwriter") ospf_config.to_excel(f, sheet_name="ospf_config", engine="xlsxwriter") ospf_area_config.to_excel(f, sheet_name="ospf_area_config", engine="xlsxwriter") ospf_interface.to_excel(f, sheet_name="ospf_interface", engine="xlsxwriter") bgp_config.to_excel(f, sheet_name="bgp_config", engine="xlsxwriter") bgp_peer_config.to_excel(f, sheet_name="bgp_peer_config", engine="xlsxwriter") bgp_session.to_excel(f, sheet_name="bgp_session", engine="xlsxwriter") routing.to_excel(f, sheet_name="routing_table", engine="xlsxwriter") f5_vip.to_excel(f, sheet_name="f5_vip", engine="xlsxwriter") named_structure.to_excel(f, sheet_name="named_structure", engine="xlsxwriter") def_structure.to_excel(f, sheet_name="defined_structures", engine="xlsxwriter") ref_structure.to_excel(f, sheet_name="referrenced_structures", engine="xlsxwriter") undefined_references.to_excel(f, sheet_name="undefined_references", engine="xlsxwriter") unused_structure.to_excel(f, sheet_name="unused_structure", engine="xlsxwriter")