Beispiel #1
0
def test_controlplane(isFailed):
    # Define a list of Spine switches
    spines = set(bfq.nodeProperties(nodes='spine.*').answer().frame()['Node'])
    logging.info("Progress: Analyzing control plane properties")

    # Get all BGP session status for leaf nodes
    bgp = bfq.bgpSessionStatus(nodes='leaf.*').answer().frame()

    # All leaves should have at least one peering with each spine
    violators = bgp.groupby('Node').filter(
        lambda x: set(x['Remote_Node']).difference(spines) != set([]))
    if len(violators) > 0:
        logging.error(
            "Found leaves that do not have at least one peering to each spine")
        logging.error(violators[['Node', 'Remote_Node']])
        isFailed = True
    else:
        logging.info("All leaves have at least one peering with each spine")

    # All leaves should only peer with spines
    non_spines = bgp[~bgp['Remote_Node'].str.contains('spine', na=False)]
    if len(non_spines) > 0:
        logging.error("Leaves do not only peer with spines")
        logging.error(non_spines[['Node', 'Remote_Node']])
        isFailed = True
    else:
        logging.info("Leaves only peer with spines")

    return isFailed
Beispiel #2
0
def plot_bgp_graph():
    """
    This function extracts BGP session compatibility and plots a graph of 
    BGP neighborships.
    """
    # Run batfish query to identify BGP neighbors
    bgpneigh = bfq.bgpSessionStatus().answer().frame()
    # Conditional check to ensure the BGP session list is not empty
    if bgpneigh.empty:
        print(Fore.RED + " ==> NO BGP NEIGHBORS FOUND")
    else:
        print(Fore.YELLOW + " ==> PLOTTING BGP GRAPH")
        bgpneigh_json = json.loads(bgpneigh.to_json(orient="index"))
        # Initialise list to track nodes that are already plotted.
        mapped_node = []
        # Initialise list to track links that are already plotted
        mapped_link_list = []
        # initialise a drawing named BGP
        diagram.add_diagram("BGP")
        for key in bgpneigh_json:
            # Initialise local list to map current link and reverse of current link.
            current_link = []
            current_link_reverse = []
            # Extract details of the neighbor
            neighbor = bgpneigh_json[key]
            # Extract node id and remote node if of each neighbor
            node_id = f'{neighbor["Node"]}\n({neighbor["Local_AS"]})'
            remote_node_id = f'{neighbor["Remote_Node"]}\n({neighbor["Remote_AS"]})'
            # Check if node has already been plotted
            # plot the node is not and add node to mapped_node list
            if node_id not in mapped_node:
                diagram.add_node(id=f"{node_id}")
                mapped_node.append(node_id)
            # Check if remote node has already been plotted
            # plot the remote node is not and add remote node to mapped_node list
            if remote_node_id not in mapped_node:
                diagram.add_node(id=f"{remote_node_id}")
                mapped_node.append(remote_node_id)
            # Extract details of current link and reverse of the current link
            current_link = [f"{node_id}", f"{remote_node_id}"]
            current_link_reverse = [f"{remote_node_id}", f"{node_id}"]
            if current_link not in mapped_link_list:
                diagram.add_link(
                    f"{node_id}",
                    f"{remote_node_id}",
                    label=f'{node_id}({neighbor["Local_IP"]})'
                    f' == {neighbor["Established_Status"]}'
                    f' == {remote_node_id}({neighbor["Remote_IP"]})',
                )
                mapped_link_list.append(current_link)
                mapped_link_list.append(current_link_reverse)
    def check_bgp_peers(self):
        not_established_peers = list()
        bgp_peers = bfq.bgpSessionStatus().answer()
        for peer in bgp_peers.rows:
            if peer.get('Established_Status') != 'ESTABLISHED':
                not_established_peers.append(
                    dict.fromkeys(
                        peer.get('Local_IP').split(),
                        peer.get('Remote_IP').get('value')))

        if len(not_established_peers) == 0:
            return 1
        else:
            logger.warn('BGP neighbors are not in an established state:')
            for neighborship in not_established_peers:
                for peer in neighborship:
                    logger.warn('{} - {}'.format(peer, neighborship.get(peer)))
            return 0
Beispiel #4
0
    "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 ********"
)
for spineloopback0 in spine_lo0:
    routes_filtered = bfq.routes(network=spineloopback0).answer().frame()
    print(routes_filtered)

#Check to see if leaf 1 can traceroute to all devices
#for device in devices:
#   headers = HeaderConstraints(dstIps=device)
#  print(bfq.traceroute(startLocation="leaf1[Loopback0]", headers=headers).answer().frame())
print(bgp_sess_comp.answer().frame())

# Bgp Session status
print("#"*100)
print("Return the status of configured BGP sessions.")
print("#"*100)
bgp_sess_status = bfq.bgpSessionCompatibility(nodes='arista', remoteNodes='n9k')
print(bgp_sess_status.answer().frame())
bgp_sess_status = bfq.bgpSessionCompatibility(nodes='n9k', remoteNodes='arista')
print(bgp_sess_status.answer().frame())

# Bgp session
print("#"*100)
print("Another way to return bgp session status")
print("#"*100)
print((bfq.bgpSessionStatus(nodes='arista').answer()).frame())

# Defined Structures
print("#"*100)
print("Lists the structures defined in the network, along with the files and line numbers in which they are defined.")
print("#"*100)
print(bfq.definedStructures().answer().frame())

# Detect Loops 
print("#"*100)
print("Detect forwarding loops.")
print("#"*100)
print(bfq.detectLoops().answer().frame())

# List edges types
print("#"*100)
Beispiel #6
0
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")
Beispiel #7
0
import re
import pandas as pd

NETWORK_NAME = "cumulus"
BASE_SNAPSHOT_NAME = "cumulus"
SNAPSHOT_PATH = "/Users/anthony/batfish/networks/example/candidate"

load_questions()

print("[*] Initializing BASE_SNAPSHOT")
bf_set_network(NETWORK_NAME)
bf_init_snapshot(SNAPSHOT_PATH, name=BASE_SNAPSHOT_NAME, overwrite=True)


#print(bfq.bgpSessionStatus().answer().frame())
bgpLeafStatus = bfq.bgpSessionStatus(nodes="/leaf/").answer().frame()
#bgpSessStatus.set_index("Node", inplace=True)
#print(bgpSessStatus.loc[['leaf01'], ['Remote_Node']])
#print(bgpSessStatus.loc['leaf01'].Remote_Node)

for index, row in bgpLeafStatus.iterrows():
	#print(row['Node'], row['Remote_Node'])
	if(re.match(r'spine', str(row['Remote_Node'])) is not None):
		print("%s Has A Matching Spine BGP Neighbor" %str(row['Node']))
	else:
		print("%s Does NOT Have A Matching Spine BGP Neighbor" %str(row['Node']))

#############################################################################################################
bgpSpineStatus = bfq.bgpSessionStatus(nodes="/spine/").answer().frame()

for index, row in bgpSpineStatus.iterrows():
Beispiel #8
0
import pandas as pd
from pybatfish.client.commands import *
from pybatfish.datamodel import Edge, Interface
from pybatfish.datamodel.answer import TableAnswer
from pybatfish.datamodel.flow import (HeaderConstraints, PathConstraints)
from pybatfish.question import bfq, load_questions


# batfish host
bf_session.host = "localhost"
load_questions()


bf_set_network('neteng-lab')
bf_init_snapshot('/home/lab/repos/network-ci-pipeline/batfish-snapshots', name='neteng-lab', overwrite=True)


pd.set_option('display.min_rows', 400)
pd.set_option('display.max_rows', 400)


bgpSessStat = bfq.bgpSessionStatus(nodes='vmx-01', remoteNodes='vmx-02', status='Established').answer().frame()
print(bgpSessStat)


bgpSessStat[bgpSessStat.Established_Status == "ESTABLISHED"]
assert len(bgpSessStat[bgpSessStat.Established_Status == "ESTABLISHED"]) == 1, "BGP session Down"
        
Beispiel #9
0
from pybatfish.client.commands import *
from pybatfish.question.question import load_questions
from pybatfish.datamodel.flow import (HeaderConstraints,PathConstraints)
from pybatfish.question import bfq

NETWORK_NAME = "cumulus"
BASE_SNAPSHOT_NAME = "cumulus"
SNAPSHOT_PATH = "/Users/anthony/batfish/networks/example/candidate"

load_questions()

print("[*] Initializing BASE_SNAPSHOT")
bf_set_network(NETWORK_NAME)
bf_init_snapshot(SNAPSHOT_PATH, name=BASE_SNAPSHOT_NAME, overwrite=True)

bgpSessStat = bfq.bgpSessionStatus().answer().frame()
print(bgpSessStat)
if len(bgpSessStat[bgpSessStat['Established_Status'] != 'ESTABLISHED']) > 0:
  print("Not All Devices Are Established")
else:
  print("All BGP Sessions Are Good")