コード例 #1
0
def remove_parallel_switch_links(anm):
    g_phy = anm['phy']
    subs = ank_utils.connected_subgraphs(g_phy, g_phy.switches())
    for component in subs:
        log.debug("Checking for multiple links to switch cluster %s" %
                  str(sorted(component)))

        # Collect all links into this cluster
        external_edges = []
        for switch in component:
            for edge in switch.edges():
                if edge.dst not in component:
                    external_edges.append(edge)

        # Group by the node they link to
        from collections import defaultdict
        check_dict = defaultdict(list)
        for edge in external_edges:
            check_dict[edge.dst].append(edge)

        # Check to see if any nodes have more than one link into this aggregate
        for dst, edges in check_dict.items():
            if len(edges) > 1:
                edges_to_remove = sorted(edges)[1:]  # remove all but first
                interfaces = ", ".join(
                    sorted(str(edge.dst_int['phy']) for edge in edges))
                interfaces_to_disconnect = ", ".join(
                    sorted(
                        str(edge.dst_int['phy']) for edge in edges_to_remove))
                dst.log.warning(
                    "Multiple edges exist to same switch cluster: %s (%s). Removing edges from interfaces %s"
                    % (str(sorted(component)), interfaces,
                       interfaces_to_disconnect))

                g_phy.remove_edges_from(edges_to_remove)
コード例 #2
0
ファイル: build_network.py プロジェクト: rackbone/autonetkit
def remove_parallel_switch_links(anm):
    g_phy = anm['phy']
    subs = ank_utils.connected_subgraphs(g_phy, g_phy.switches())
    for component in subs:
        log.debug("Checking for multiple links to switch cluster %s"
                  % str(sorted(component)))

        # Collect all links into this cluster
        external_edges = []
        for switch in component:
            for edge in switch.edges():
                if edge.dst not in component:
                    external_edges.append(edge)

        # Group by the node they link to
        from collections import defaultdict
        check_dict = defaultdict(list)
        for edge in external_edges:
            check_dict[edge.dst].append(edge)

        # Check to see if any nodes have more than one link into this aggregate
        for dst, edges in check_dict.items():
            if len(edges) > 1:
                edges_to_remove = sorted(edges)[1:]  # remove all but first
                interfaces = ", ".join(
                    sorted(str(edge.dst_int['phy']) for edge in edges))
                interfaces_to_disconnect = ", ".join(sorted(str(edge.dst_int['phy'])
                                                            for edge in edges_to_remove))
                dst.log.warning(
                    "Multiple edges exist to same switch cluster: "
                    " %s (%s). Removing edges from interfaces %s" % (
                    str(sorted(component)), interfaces, interfaces_to_disconnect))

                g_phy.remove_edges_from(edges_to_remove)
コード例 #3
0
ファイル: layer2.py プロジェクト: datacenter/ignite
def build_vlans(anm):
    import itertools
    from collections import defaultdict
    g_l2 = anm['layer2']
    g_l1_conn = anm['layer1_conn']
    g_phy = anm['phy']

    g_vtp = anm.add_overlay('vtp')
    # g_vlan = anm.add_overlay('vlan')
    managed_switches = [n for n in g_l2.switches()
                        if n.device_subtype == "managed"]

    g_vtp.add_nodes_from(g_l1_conn)
    g_vtp.add_edges_from(g_l1_conn.edges(), retain=['link_type'])

    edges_to_remove = [edge for edge in g_l1_conn.edges()
                      if edge.link_type == 'is_not_l2']

    g_vtp.remove_edges_from(edges_to_remove)
    edges_to_remove =[]

    # remove anything not a managed_switch or connected to a managed_switch
    keep = set()
    keep.update(managed_switches)
    for switch in managed_switches:
        keep.update(switch['vtp'].neighbors())

    remove = set(g_vtp) - keep
    g_vtp.remove_nodes_from(remove)

    edges_to_remove = [e for e in g_vtp.edges()
                       if not(e.src in managed_switches or e.dst in managed_switches)]
    g_vtp.remove_edges_from(edges_to_remove)

    # import ipdb
    # ipdb.set_trace()
    set_default_vlans(anm)

    # copy across vlans from input graph
    vswitch_id_counter = itertools.count(1)

    # TODO: aggregate managed switches

    bcs_to_trim = set()

    subs = ank_utils.connected_subgraphs(g_vtp, managed_switches)
    for sub in subs:
        # identify the VLANs on these switches
        vlans = defaultdict(list)
        sub_neigh_ints = set()
        for switch in sub:
            l2_switch = switch['layer2']
            bcs_to_trim.update(l2_switch.neighbors())
            neigh_ints = {iface for iface in switch.neighbor_interfaces()
                          if iface.node.is_l3device()
                          and iface.node not in sub}

            sub_neigh_ints.update(neigh_ints)

        for interface in sub_neigh_ints:
            # store keyed by vlan id
            vlan = interface['vtp'].vlan
            vlans[vlan].append(interface)

        log.debug("Vlans for sub %s are %s", sub, vlans)
        # create a virtual switch for each
        # TODO: naming: if this is the only pair then name after these, else
        # use the switch names too
        #vswitch_prefix = "_".join(str(sw) for sw in sub)
        vswitches = []  # store to connect trunks
        for vlan, interfaces in vlans.items():
            # create a virtual switch
            vswitch_id = "vswitch%s" % vswitch_id_counter.next()
            # vswitch = g_vlan.add_node(vswitch_id)
            vswitch = g_l2.add_node(vswitch_id)
            # TODO: check of switch or just broadcast_domain for higher layer
            # purposes
            vswitch.device_type = "switch"
            vswitch.device_subtype = "virtual"
            vswitches.append(vswitch)
            # TODO: layout based on midpoint of previous?
            # or if same number as real switches, use their co-ordinates?
            # and then check for coincident?
            vswitch.x = sum(
                i.node['phy'].x for i in interfaces) / len(interfaces) + 50
            vswitch.y = sum(
                i.node['phy'].y for i in interfaces) / len(interfaces) + 50
            vswitch.vlan = vlan

            vswitch['layer2'].broadcast_domain = True
            vswitch['layer2'].vlan = vlan

            # and connect from vswitch to the interfaces
            edges_to_add = [(vswitch, iface) for iface in interfaces]
            g_l2.add_edges_from(edges_to_add, retain=['link_type'])

        # remove the physical switches
        g_l2.remove_nodes_from(bcs_to_trim)
        g_l2.remove_nodes_from(sub)
        # TODO: also remove any broadcast domains no longer connected

        # g_l2.remove_nodes_from(disconnected_bcs)

        # Note: we don't store the interface names as ciuld clobber
        # eg came from two physical switches, each on gige0
        # if need, work backwards from the router iface and its connectivity

        # and add the trunks
        # TODO: these need annotations!
        # create trunks
        edges_to_add = list(itertools.combinations(vswitches, 2))
        # TODO: ensure only once
        # TODO: filter so only one direction
        # g_vlan.add_edges_from(edges_to_add, trunk=True)
        g_vtp.add_edges_from(edges_to_add, trunk=True, retain=['link_type'])
コード例 #4
0
ファイル: layer2.py プロジェクト: plucena24/autonetkit
def build_vlans(anm):
    import itertools
    from collections import defaultdict
    g_l2 = anm['layer2']
    g_vlan_trunk = anm.add_overlay('vlan_trunk')
    g_vlans = anm.add_overlay('vlans')
    managed_switches = [n for n in g_l2.switches()
                        if n.device_subtype == "managed"]

    # copy across vlans from input graph
    for router in g_l2.routers():
        for interface in router.physical_interfaces():
            interface.vlan = interface['input'].vlan
            if not interface.vlan:
                pass
                # check if connectde to a managed switch, if so, warn

    vswitch_id_counter = itertools.count(1)

    subs = ank_utils.connected_subgraphs(g_l2, managed_switches)
    for sub in subs:
        # identify the VLANs on these switches
        vlans = defaultdict(list)
        for switch in sub:
            neigh_ints = [i.neighbors()[0] for i in switch.interfaces()
                          if i.is_bound]
            router_ints = [i for i in neigh_ints if i.node.is_router()]
            for interface in router_ints:
                # store keyed by vlan id
                vlans[interface.vlan].append(interface)

        # create a virtual switch for each
        # TODO: naming: if this is the only pair then name after these, else
        # use the switch names too
        #vswitch_prefix = "_".join(str(sw) for sw in sub)
        vswitches = []  # store to connect trunks
        for vlan, interfaces in vlans.items():
            # create a virtual switch
            vswitch_id = "vswitch%s" % vswitch_id_counter.next()
            vswitch = g_vlans.add_node(vswitch_id)
            vswitch.device_type = "switch"
            vswitch.device_subtype = "virtual"
            vswitches.append(vswitch)
            # TODO: layout based on midpoint of previous?
            # or if same number as real switches, use their co-ordinates?
            # and then check for coincident?
            vswitch.x = sum(
                i.node['phy'].x for i in interfaces) / len(interfaces) + 50
            vswitch.y = sum(
                i.node['phy'].y for i in interfaces) / len(interfaces) + 50
            vswitch.vlan = vlan

            g_vlan_trunk.add_node(vswitch)

            # and connect from vswitch to the interfaces
            edges_to_add = [(vswitch, iface) for iface in interfaces]
            g_l2.add_edges_from(edges_to_add)

        # remove the physical switches
        g_l2.remove_nodes_from(sub)

        # Note: we don't store the interface names as ciuld clobber
        # eg came from two physical switches, each on gige0
        # if need, work backwards from the router iface and its connectivity

        # and add the trunks
        # TODO: these need annotations!
        # create trunks
        edges_to_add = list(itertools.combinations(vswitches, 2))
        # TODO: ensure only once
        # TODO: filter so only one direction
        g_l2.add_edges_from(edges_to_add, trunk=True)
        g_vlan_trunk.add_edges_from(edges_to_add, trunk=True)
コード例 #5
0
def build_vlans(anm):
    import itertools
    from collections import defaultdict
    g_l2 = anm['layer2']
    g_l1_conn = anm['layer1_conn']
    g_phy = anm['phy']

    g_vtp = anm.add_overlay('vtp')
    # g_vlan = anm.add_overlay('vlan')
    managed_switches = [
        n for n in g_l2.switches() if n.device_subtype == "managed"
    ]

    g_vtp.add_nodes_from(g_l1_conn)
    g_vtp.add_edges_from(g_l1_conn.edges(), retain=['link_type'])

    edges_to_remove = [
        edge for edge in g_l1_conn.edges() if edge.link_type == 'is_not_l2'
    ]

    g_vtp.remove_edges_from(edges_to_remove)
    edges_to_remove = []

    # remove anything not a managed_switch or connected to a managed_switch
    keep = set()
    keep.update(managed_switches)
    for switch in managed_switches:
        keep.update(switch['vtp'].neighbors())

    remove = set(g_vtp) - keep
    g_vtp.remove_nodes_from(remove)

    edges_to_remove = [
        e for e in g_vtp.edges()
        if not (e.src in managed_switches or e.dst in managed_switches)
    ]
    g_vtp.remove_edges_from(edges_to_remove)

    # import ipdb
    # ipdb.set_trace()
    set_default_vlans(anm)

    # copy across vlans from input graph
    vswitch_id_counter = itertools.count(1)

    # TODO: aggregate managed switches

    bcs_to_trim = set()

    subs = ank_utils.connected_subgraphs(g_vtp, managed_switches)
    for sub in subs:
        # identify the VLANs on these switches
        vlans = defaultdict(list)
        sub_neigh_ints = set()
        for switch in sub:
            l2_switch = switch['layer2']
            bcs_to_trim.update(l2_switch.neighbors())
            neigh_ints = {
                iface
                for iface in switch.neighbor_interfaces()
                if iface.node.is_l3device() and iface.node not in sub
            }

            sub_neigh_ints.update(neigh_ints)

        for interface in sub_neigh_ints:
            # store keyed by vlan id
            vlan = interface['vtp'].vlan
            vlans[vlan].append(interface)

        log.debug("Vlans for sub %s are %s", sub, vlans)
        # create a virtual switch for each
        # TODO: naming: if this is the only pair then name after these, else
        # use the switch names too
        #vswitch_prefix = "_".join(str(sw) for sw in sub)
        vswitches = []  # store to connect trunks
        for vlan, interfaces in vlans.items():
            # create a virtual switch
            vswitch_id = "vswitch%s" % vswitch_id_counter.next()
            # vswitch = g_vlan.add_node(vswitch_id)
            vswitch = g_l2.add_node(vswitch_id)
            # TODO: check of switch or just broadcast_domain for higher layer
            # purposes
            vswitch.device_type = "switch"
            vswitch.device_subtype = "virtual"
            vswitches.append(vswitch)
            # TODO: layout based on midpoint of previous?
            # or if same number as real switches, use their co-ordinates?
            # and then check for coincident?
            vswitch.x = sum(i.node['phy'].x
                            for i in interfaces) / len(interfaces) + 50
            vswitch.y = sum(i.node['phy'].y
                            for i in interfaces) / len(interfaces) + 50
            vswitch.vlan = vlan

            vswitch['layer2'].broadcast_domain = True
            vswitch['layer2'].vlan = vlan

            # and connect from vswitch to the interfaces
            edges_to_add = [(vswitch, iface) for iface in interfaces]
            g_l2.add_edges_from(edges_to_add, retain=['link_type'])

        # remove the physical switches
        g_l2.remove_nodes_from(bcs_to_trim)
        g_l2.remove_nodes_from(sub)
        # TODO: also remove any broadcast domains no longer connected

        # g_l2.remove_nodes_from(disconnected_bcs)

        # Note: we don't store the interface names as ciuld clobber
        # eg came from two physical switches, each on gige0
        # if need, work backwards from the router iface and its connectivity

        # and add the trunks
        # TODO: these need annotations!
        # create trunks
        edges_to_add = list(itertools.combinations(vswitches, 2))
        # TODO: ensure only once
        # TODO: filter so only one direction
        # g_vlan.add_edges_from(edges_to_add, trunk=True)
        g_vtp.add_edges_from(edges_to_add, trunk=True, retain=['link_type'])