示例#1
0
def get_reachable_interfaces(snapshot: str, switches: Set[str]) -> Set[str]:
    # bf_init_snapshot(str(snapshot), "reachable", overwrite=True)
    nodes = []
    results = bfq.nodeProperties().answer().frame()
    for _, result in results.iterrows():
        nodes.append(result.Node)
    reachable = set()
    for switch in switches:
        for node in nodes:
            results = bfq.reachability(
                pathConstraints=PathConstraints(startLocation=switch, endLocation=node)) \
                .answer(snapshot=snapshot)
            results = results.frame()
            for _, result in results.iterrows():
                for trace in result.Traces:
                    for hop in trace.hops:
                        for step in hop.steps:
                            if hasattr(step.detail, "outputInterface"):
                                reachable.add(
                                    f"{hop.node}:{step.detail.outputInterface}"
                                )
                            if hasattr(step.detail, "inputInterface"):
                                reachable.add(
                                    f"{hop.node}:{step.detail.inputInterface}")
    return reachable
示例#2
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
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
示例#4
0
 def resolve(self) -> Dict[str, Set[str]]:
     data = {}
     result = bfq.nodeProperties(
         nodes=self.node_spec,
         properties=self.node_property).answer().frame()
     for node in result.Node.values:
         data[node] = self.commands
     return data
示例#5
0
def resolve(node_spec: str, node_property: str, snapshot: str):
    data = set()
    load_questions()
    result = bfq.nodeProperties(nodes=node_spec,
                                properties=node_property)\
        .answer(snapshot=snapshot).frame()
    for node in result.Node.values:
        data.add(node)
    return data
示例#6
0
def init_bf():
    bf_session.host = bf_host

    bf_set_network("nova_candidate")
    snapshots = bf_list_snapshots()
    pprint(snapshots)
    bf_init_snapshot(SNAPSHOT_DIR, name=SNAPSHOT_NAME, overwrite=True)

    bf_set_snapshot(SNAPSHOT_NAME)

    load_questions()

    print(bfq.initIssues().answer())
    print(
        bfq.nodeProperties(properties="Configuration_Format").answer().frame())
def deactivate_nodes(bf_snapshot_base, bf_snapshot_fail):
    nodes = bfq.nodeProperties(nodes=NODE_SCOPE).answer().frame()

    for node_index in range(len(nodes)):
        print(
            "[*] Deactivating node: [magenta bold]{}[/magenta bold]".format(
                nodes.loc[node_index].Node),
            end=" ",
        )
        bf_fork_snapshot(
            base_name=bf_snapshot_base,
            name=bf_snapshot_fail,
            deactivate_nodes=[nodes.loc[node_index].Node],
            overwrite=True,
        )
        pprint_results(
            get_differential_reachability(bf_snapshot_base, bf_snapshot_fail))
示例#8
0
def get_reachable_nodes_intersect(snapshot: str,
                                  switches: Set[str]) -> Set[str]:
    nodes = []
    results = bfq.nodeProperties().answer().frame()
    for _, result in results.iterrows():
        nodes.append(result.Node)
    reachable = {}
    for switch in switches:
        for node in nodes:
            results = bfq.reachability(
                pathConstraints=PathConstraints(startLocation=switch, endLocation=node)) \
                .answer(snapshot=snapshot)
            results = results.frame()
            if results.size > 0:
                if node not in reachable:
                    reachable[node] = 0
                reachable[node] += 1
    return set(
        map(
            lambda it: it[0],
            filter(lambda elem: elem[1] >= len(switches) // 3,
                   reachable.items())))
def print_debugging_info():
    parse_status = bfq.fileParseStatus().answer().frame()

    print("----------------------")

    print(parse_status)

    print("----------------------")

    parse_warning = bfq.parseWarning().answer().frame()

    print("----------------------")

    print(parse_warning)

    print("----------------------")

    # vxlanEdges,layer3Edges
    node_properties_trunc = bfq.nodeProperties(
        properties="Interfaces").answer().frame()

    print(node_properties_trunc)

    print("---------")
    print(bfq.undefinedReferences().answer().frame())

    print("layer1Edges")
    print("----------------------")
    print(bfq.layer1Edges().answer().frame())
    print("LAYER3_EDGES")
    print("----------------------")
    print(bfq.layer3Edges().answer().frame())
    print("----------------------")

    print(bfq.undefinedReferences().answer().frame())

    # Get edges of type layer 3 (IP layer)
    print(bfq.edges(edgeType="layer3").answer().frame())
示例#10
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")
示例#11
0
# Now create the network and initialize the snapshot
bf_session.host = BF_HOST
load_questions()
# bf_set_network(NETWORK_NAME)
# bf_init_snapshot(SNAPSHOT_PATH, name=SNAPSHOT_NAME, overwrite=True)
print(acl_text)
acl_snapshot = bf_session.init_snapshot_from_text(acl_text,
                                                  platform="arista",
                                                  snapshot_name="original",
                                                  overwrite=True)

# node_name = "DMZ-LF18"  # The router to change
# filter_name = "demo"      # Name of the ACL to change

result = bfq.nodeProperties().answer().frame()
# permiturl = 'http://dmz-gitlab.sjc.aristanetworks.com/network/cloudvision/-/raw/master/permit.json'
permit_url = GITLAB_API_URL + "/projects/" + GITLAB_PROJECT_ID + \
    "/repository/files" + "/permit.json" + "/raw?ref=" + GITLAB_BRANCH
resp = requests.get(permit_url, headers=tokenheader)
permits = resp.json()
print(f"ACL SNAPSHOT: {acl_snapshot}")
for p in permits['permit']:
    headers = HeaderConstraints(dstIps=p["dstIps"],
                                ipProtocols=p["ipProtocols"],
                                dstPorts=p["dstPorts"])
    # print(headers)
    # answer = bfq.searchFilters(headers=headers,
    #                            action="permit").answer(snapshot=SNAPSHOT_NAME)
    answer2 = bfq.searchFilters(headers=headers,
                                action="permit").answer(snapshot=acl_snapshot)