Esempio n. 1
0
def shortest_path(nm_graph, src, dst):

    # TODO: move to utils
# TODO: use networkx boundary nodes directly: does the same thing

    graph = unwrap_graph(nm_graph)
    src_id = unwrap_nodes(src)
    dst_id = unwrap_nodes(dst)

    #TODO: check path works for muli-edge graphs too
    path = nx.shortest_path(graph, src_id, dst_id)

    return wrap_nodes(nm_graph, path)
Esempio n. 2
0
def shortest_path(nm_graph, src, dst):

    # TODO: move to utils
    # TODO: use networkx boundary nodes directly: does the same thing

    graph = unwrap_graph(nm_graph)
    src_id = unwrap_nodes(src)
    dst_id = unwrap_nodes(dst)

    # TODO: check path works for muli-edge graphs too
    path = nx.shortest_path(graph, src_id, dst_id)

    return wrap_nodes(nm_graph, path)
Esempio n. 3
0
def neigh_average(
    NmGraph,
    node,
    attribute,
    attribute_graph=None,
    ):
    """
    averages out attribute from neighbors in specified NmGraph
    attribute_graph is the graph to read the attribute from
    if property is numeric, then return mean
    else return most frequently occuring value
    """

    graph = unwrap_graph(NmGraph)
    if attribute_graph:
        attribute_graph = unwrap_graph(attribute_graph)
    else:
        attribute_graph = graph  # use input graph
    node = unwrap_nodes(node)
    values = [attribute_graph.node[n].get(attribute) for n in
              graph.neighbors(node)]

# TODO: use neigh_attr

    try:
        values = [float(val) for val in values]
        return sum(values) / len(values)
    except ValueError:
        return most_frequent(values)
Esempio n. 4
0
def aggregate_nodes(nm_graph, nodes, retain=None):
    """Combines connected into a single node"""
    if retain is None:
        retain = []

    try:
        retain.lower()
        retain = [retain]  # was a string, put into list
    except AttributeError:
        pass  # already a list

    nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(nm_graph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):

        # print "Nothing to aggregate for %s: no edges in subgraph"

        pass
    total_added_edges = []
    if graph.is_directed():
        component_nodes_list = nx.strongly_connected_components(subgraph)
    else:
        component_nodes_list = nx.connected_components(subgraph)
    for component_nodes in component_nodes_list:
        if len(component_nodes) > 1:
            component_nodes = [nm_graph.node(n) for n in component_nodes]

            # TODO: could choose most connected, or most central?
            # TODO: refactor so use nodes_to_remove

            nodes_to_remove = list(component_nodes)
            base = nodes_to_remove.pop()  # choose a base device to retain
            log.debug("Retaining %s, removing %s", base, nodes_to_remove)

            external_edges = []
            for node in nodes_to_remove:
                external_edges += [e for e in node.edges() if e.dst not in component_nodes]
                # all edges out of component

            log.debug("External edges %s", external_edges)
            edges_to_add = []
            for edge in external_edges:
                dst = edge.dst
                data = dict((key, edge._data.get(key)) for key in retain)
                ports = edge.raw_interfaces
                dst_int_id = ports[dst.node_id]

                # TODO: bind to (and maybe add) port on the new switch?

                data["_ports"] = {dst.node_id: dst_int_id}

                append = (base.node_id, dst.node_id, data)
                edges_to_add.append(append)

            nm_graph.add_edges_from(edges_to_add)
            total_added_edges += edges_to_add
            nm_graph.remove_nodes_from(nodes_to_remove)

    return wrap_edges(nm_graph, total_added_edges)
Esempio n. 5
0
def set_node_default(nm_graph, nbunch=None, **kwargs):
    """Sets all nodes in nbunch to value if key not already set
    Note: this won't apply to future nodes added

    >>> anm = autonetkit.topos.house()
    >>> g_phy = anm['phy']
    >>> r1 = g_phy.node("r1")
    >>> r1.color = "blue"
    >>> [(n, n.color) for n in g_phy]
    [(r4, None), (r5, None), (r1, 'blue'), (r2, None), (r3, None)]
    >>> set_node_default(g_phy, color="red")
    >>> [(n, n.color) for n in g_phy]
    [(r4, 'red'), (r5, 'red'), (r1, 'blue'), (r2, 'red'), (r3, 'red')]

    Can also set for a specific bunch of nodes

    >>> nodes = ["r1", "r2", "r3"]
    >>> set_node_default(g_phy, nodes, role="core")
    >>> [(n, n.role) for n in g_phy]
    [(r4, None), (r5, None), (r1, 'core'), (r2, 'core'), (r3, 'core')]

    """

    # work with the underlying NetworkX graph for efficiency
    graph = unwrap_graph(nm_graph)
    if nbunch is None:
        nbunch = graph.nodes()
    else:
        nbunch = unwrap_nodes(nbunch)
    for node in nbunch:
        for (key, val) in kwargs.items():
            if key not in graph.node[node]:
                graph.node[node][key] = val
Esempio n. 6
0
def set_node_default(nm_graph, nbunch=None, **kwargs):
    """Sets all nodes in nbunch to value if key not already set
    Note: this won't apply to future nodes added

    >>> anm = autonetkit.topos.house()
    >>> g_phy = anm['phy']
    >>> r1 = g_phy.node("r1")
    >>> r1.color = "blue"
    >>> [(n, n.color) for n in g_phy]
    [(r4, None), (r5, None), (r1, 'blue'), (r2, None), (r3, None)]
    >>> set_node_default(g_phy, color="red")
    >>> [(n, n.color) for n in g_phy]
    [(r4, 'red'), (r5, 'red'), (r1, 'blue'), (r2, 'red'), (r3, 'red')]

    Can also set for a specific bunch of nodes

    >>> nodes = ["r1", "r2", "r3"]
    >>> set_node_default(g_phy, nodes, role="core")
    >>> [(n, n.role) for n in g_phy]
    [(r4, None), (r5, None), (r1, 'core'), (r2, 'core'), (r3, 'core')]

    """

    # work with the underlying NetworkX graph for efficiency
    graph = unwrap_graph(nm_graph)
    if nbunch is None:
        nbunch = graph.nodes()
    else:
        nbunch = unwrap_nodes(nbunch)
    for node in nbunch:
        for (key, val) in kwargs.items():
            if key not in graph.node[node]:
                graph.node[node][key] = val
Esempio n. 7
0
File: ank.py Progetto: wilko77/STRIP
def explode_nodes(overlay_graph, nodes, retain = []):
    """Explodes all nodes in nodes
    TODO: explain better
    TODO: Add support for digraph - check if overlay_graph.is_directed()
    """
    log.debug("Exploding nodes")
    try:
        retain.lower()
        retain = [retain] # was a string, put into list
    except AttributeError:
        pass # already a list

    graph = unwrap_graph(overlay_graph)
    nodes = unwrap_nodes(nodes)
    added_edges = []
#TODO: need to keep track of edge_ids here also?
    nodes = list(nodes)
    for node in nodes:
        log.debug("Exploding from %s" % node)
        neighbors = graph.neighbors(node)
        neigh_edge_pairs = ( (s,t) for s in neighbors for t in neighbors if s != t)
        edges_to_add = []
        for (src, dst) in neigh_edge_pairs:
            src_to_node_data = dict( (key, graph[src][node][key]) for key in retain)
            node_to_dst_data = dict( (key, graph[node][dst][key]) for key in retain)
            src_to_node_data.update(node_to_dst_data)
            edges_to_add.append((src, dst, src_to_node_data))

        graph.add_edges_from(edges_to_add)
        added_edges.append(edges_to_add)

        graph.remove_node(node)

    return wrap_edges(overlay_graph, added_edges)
Esempio n. 8
0
File: ank.py Progetto: sk2/ANK-NG
def explode_nodes(overlay_graph, nodes, retain = []):
    """Explodes all nodes in nodes
    TODO: explain better
    """
    try:
        retain.lower()
        retain = [retain] # was a string, put into list
    except AttributeError:
        pass # already a list

    graph = unwrap_graph(overlay_graph)
    nodes = unwrap_nodes(nodes)
    added_edges = []
#TODO: need to keep track of edge_ids here also?
    nodes = list(nodes)
    for node in nodes:
        neighbors = graph.neighbors(node)
        neigh_edge_pairs = ( (s,t) for s in neighbors for t in neighbors if s != t)
        edges_to_add = []
        for (src, dst) in neigh_edge_pairs:
            data = dict( (key, graph[src][dst][key]) for key in retain)
            edges_to_add.append((src, dst, data))

        graph.add_edges_from(edges_to_add)
        added_edges.append(edges_to_add)

        graph.remove_node(node)

    return wrap_edges(overlay_graph, added_edges)
Esempio n. 9
0
File: ank.py Progetto: sk2/ANK-NG
def explode_nodes(overlay_graph, nodes, retain=[]):
    """Explodes all nodes in nodes
    TODO: explain better
    """
    try:
        retain.lower()
        retain = [retain]  # was a string, put into list
    except AttributeError:
        pass  # already a list

    graph = unwrap_graph(overlay_graph)
    nodes = unwrap_nodes(nodes)
    added_edges = []
    #TODO: need to keep track of edge_ids here also?
    nodes = list(nodes)
    for node in nodes:
        neighbors = graph.neighbors(node)
        neigh_edge_pairs = ((s, t) for s in neighbors for t in neighbors
                            if s != t)
        edges_to_add = []
        for (src, dst) in neigh_edge_pairs:
            data = dict((key, graph[src][dst][key]) for key in retain)
            edges_to_add.append((src, dst, data))

        graph.add_edges_from(edges_to_add)
        added_edges.append(edges_to_add)

        graph.remove_node(node)

    return wrap_edges(overlay_graph, added_edges)
Esempio n. 10
0
def connected_subgraphs(nm_graph, nodes=None):
    """

    >>> anm = autonetkit.topos.house()
    >>> g_phy = anm['phy']
    >>> connected_subgraphs(g_phy)
    [[r4, r5, r1, r2, r3]]
    >>> edges = [("r2", "r4"), ("r3", "r5")]
    >>> g_phy.remove_edges_from(edges)
    >>> connected_subgraphs(g_phy)
    [[r1, r2, r3], [r4, r5]]


    """
    if nodes is None:
        nodes = nm_graph.nodes()
    else:
        nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(nm_graph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):

        # print "Nothing to aggregate for %s: no edges in subgraph"

        pass
    if graph.is_directed():
        component_nodes_list = nx.strongly_connected_components(subgraph)
    else:
        component_nodes_list = nx.connected_components(subgraph)

    wrapped = []
    for component in component_nodes_list:
        wrapped.append(list(wrap_nodes(nm_graph, component)))

    return wrapped
Esempio n. 11
0
def set_node_default(OverlayGraph, nbunch, **kwargs):
    """Sets all nodes in nbunch to value if key not already set"""
    graph = unwrap_graph(OverlayGraph)
    nbunch = unwrap_nodes(nbunch)
    for node in nbunch:
        for key, val in kwargs.items():
            if key not in graph.node[node]:
                graph.node[node][key] = val
Esempio n. 12
0
File: ank.py Progetto: wilko77/STRIP
def set_node_default(overlay_graph, nbunch, **kwargs):
    """Sets all nodes in nbunch to value if key not already set"""
    graph = unwrap_graph(overlay_graph)
    nbunch = unwrap_nodes(nbunch)
    for node in nbunch:
        for key, val in kwargs.items():
            if key not in graph.node[node]:
                graph.node[node][key] = val
Esempio n. 13
0
def neigh_most_frequent(OverlayGraph, node, attribute, attribute_graph = None):
    """Used to explicitly force most frequent - useful if integers such as ASN which would otherwise return mean"""
    graph = unwrap_graph(OverlayGraph)
    if attribute_graph:
        attribute_graph = unwrap_graph(attribute_graph)
    else:
        attribute_graph = graph # use input graph
    node = unwrap_nodes(node)
    values = [attribute_graph.node[n].get(attribute) for n in graph.neighbors(node)]
    return most_frequent(values)
Esempio n. 14
0
File: ank.py Progetto: wilko77/STRIP
def neigh_most_frequent(overlay_graph, node, attribute, attribute_graph = None):
    """Used to explicitly force most frequent - useful if integers such as ASN which would otherwise return mean"""
    graph = unwrap_graph(overlay_graph)
    if attribute_graph:
        attribute_graph = unwrap_graph(attribute_graph)
    else:
        attribute_graph = graph # use input graph
    node = unwrap_nodes(node)
    values = [attribute_graph.node[n].get(attribute) for n in graph.neighbors(node)]
    return most_frequent(values)
Esempio n. 15
0
def boundary_nodes(graph, nodes):
    # TODO: move to utils
#TODO: use networkx boundary nodes directly: does the same thing
    """ returns nodes at boundary of G based on edge_boundary from networkx """
    graph = unwrap_graph(graph)
    nodes = list(nodes)
    nbunch = list(unwrap_nodes(nodes))
    # find boundary
    b_edges = nx.edge_boundary(graph, nbunch)  # boundary edges
    internal_nodes = [s for (s, t) in b_edges]
    assert(all(n in nbunch for n in internal_nodes))  # check internal

    return wrap_nodes(graph, internal_nodes)
Esempio n. 16
0
def boundary_nodes(graph, nodes):
    # TODO: move to utils
#TODO: use networkx boundary nodes directly: does the same thing
    """ returns nodes at boundary of G based on edge_boundary from networkx """
    graph = unwrap_graph(graph)
    nodes = list(nodes)
    nbunch = list(unwrap_nodes(nodes))
    # find boundary
    b_edges = nx.edge_boundary(graph, nbunch)  # boundary edges
    internal_nodes = [s for (s, t) in b_edges]
    assert(all(n in nbunch for n in internal_nodes))  # check internal

    return wrap_nodes(graph, internal_nodes)
Esempio n. 17
0
def set_node_default(NmGraph, nbunch = None, **kwargs):
    """Sets all nodes in nbunch to value if key not already set
    Note: this won't apply to future nodes added
    """
    graph = unwrap_graph(NmGraph)
    if nbunch is None:
        nbunch = graph.nodes()
    else:
        nbunch = unwrap_nodes(nbunch)
    for node in nbunch:
        for key, val in kwargs.items():
            if key not in graph.node[node]:
                graph.node[node][key] = val
Esempio n. 18
0
def neigh_attr(NmGraph, node, attribute, attribute_graph = None):
    #TODO: tidy up parameters to take attribute_graph first, and then evaluate if attribute_graph set, if not then use attribute_graph as attribute
#TODO: explain how NmGraph and attribute_graph work, eg for G_ip and G_phy
    graph = unwrap_graph(NmGraph)
    node = unwrap_nodes(node)
    if attribute_graph:
        attribute_graph = unwrap_graph(attribute_graph)
    else:
        attribute_graph = graph # use input graph

    #Only look at nodes which exist in attribute_graph
    neighs = (n for n in graph.neighbors(node))
    valid_nodes = (n for n in neighs if n in attribute_graph)
    return (attribute_graph.node[node].get(attribute) for node in valid_nodes)
Esempio n. 19
0
def neigh_most_frequent(NmGraph, node, attribute, attribute_graph = None, allow_none = False):
    """Used to explicitly force most frequent - useful if integers such as ASN which would otherwise return mean"""
    #TODO: rename to median?
    graph = unwrap_graph(NmGraph)
    if attribute_graph:
        attribute_graph = unwrap_graph(attribute_graph)
    else:
        attribute_graph = graph # use input graph
    node = unwrap_nodes(node)
    values = [attribute_graph.node[n].get(attribute) for n in graph.neighbors(node)]
    values = sorted(values)
    if not allow_none:
        values = [v for v in values if v is not None]
    return most_frequent(values)
Esempio n. 20
0
def set_node_default(NmGraph, nbunch=None, **kwargs):
    """Sets all nodes in nbunch to value if key not already set
    Note: this won't apply to future nodes added
    """

    graph = unwrap_graph(NmGraph)
    if nbunch is None:
        nbunch = graph.nodes()
    else:
        nbunch = unwrap_nodes(nbunch)
    for node in nbunch:
        for (key, val) in kwargs.items():
            if key not in graph.node[node]:
                graph.node[node][key] = val
Esempio n. 21
0
def neigh_attr(OverlayGraph, node, attribute, attribute_graph = None):
    #TODO: tidy up parameters to take attribute_graph first, and then evaluate if attribute_graph set, if not then use attribute_graph as attribute
#TODO: explain how OverlayGraph and attribute_graph work, eg for G_ip and G_phy
    graph = unwrap_graph(OverlayGraph)
    node = unwrap_nodes(node)
    if attribute_graph:
        attribute_graph = unwrap_graph(attribute_graph)
    else:
        attribute_graph = graph # use input graph

    #Only look at nodes which exist in attribute_graph
    neighs = (n for n in graph.neighbors(node))
    valid_nodes = (n for n in neighs if n in attribute_graph)
    return (attribute_graph.node[node].get(attribute) for node in valid_nodes)
Esempio n. 22
0
def connected_subgraphs(NmGraph, nodes):
    nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(NmGraph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):
        #print "Nothing to aggregate for %s: no edges in subgraph"
        pass
    total_added_edges = []
    if graph.is_directed():
        component_nodes_list = nx.strongly_connected_components(subgraph)
    else:
        component_nodes_list = nx.connected_components(subgraph)

    wrapped = []
    for component in component_nodes_list:
        wrapped.append(list(wrap_nodes(NmGraph, component)))

    return wrapped
Esempio n. 23
0
File: ank.py Progetto: sk2/ANK-NG
def aggregate_nodes(overlay_graph, nodes, retain=[]):
    """Combines connected into a single node"""
    try:
        retain.lower()
        retain = [retain]  # was a string, put into list
    except AttributeError:
        pass  # already a list

    nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(overlay_graph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):
        #print "Nothing to aggregate for %s: no edges in subgraph"
        pass
    total_added_edges = []
    for component_nodes in nx.connected_components(subgraph):
        if len(component_nodes) > 1:
            base = component_nodes.pop()  # choose one base device to retain
            nodes_to_remove = set(
                component_nodes
            )  # remaining nodes, set for fast membership test
            external_edges = nx.edge_boundary(graph, component_nodes)
            edges_to_add = []
            for src, dst in external_edges:
                # src is the internal node to remove
                if src == base or dst == base:
                    continue  # don't alter edges from base
                else:
                    if src in nodes_to_remove:
                        # edge from component to outside
                        data = dict(
                            (key, graph[src][dst][key]) for key in retain)
                        edges_to_add.append((base, dst, data))
                    else:
                        # edge from outside into component
                        data = dict(
                            (key, graph[dst][src][key]) for key in retain)
                        edges_to_add.append((base, src, data))
            graph.add_edges_from(edges_to_add)
            total_added_edges += edges_to_add
            graph.remove_nodes_from(nodes_to_remove)

    return wrap_edges(overlay_graph, total_added_edges)
Esempio n. 24
0
def neigh_most_frequent(nm_graph, node, attribute,
                        attribute_graph=None, allow_none=False):
    """Used to explicitly force most frequent -
    useful if integers such as ASN which would otherwise return mean"""

    # TODO: rename to median?

    graph = unwrap_graph(nm_graph)
    if attribute_graph:
        attribute_graph = unwrap_graph(attribute_graph)
    else:
        attribute_graph = graph  # use input graph
    node = unwrap_nodes(node)
    values = [attribute_graph.node[n].get(attribute) for n in
              graph.neighbors(node)]
    values = sorted(values)
    if not allow_none:
        values = [v for v in values if v is not None]
    return most_frequent(values)
Esempio n. 25
0
def explode_nodes(OverlayGraph, nodes, retain = []):
    """Explodes all nodes in nodes
    TODO: explain better
    TODO: Add support for digraph - check if OverlayGraph.is_directed()
    """
    log.debug("Exploding nodes")
    try:
        retain.lower()
        retain = [retain] # was a string, put into list
    except AttributeError:
        pass # already a list

    graph = unwrap_graph(OverlayGraph)
    nodes = unwrap_nodes(nodes)
    added_edges = []
#TODO: need to keep track of edge_ids here also?
    nodes = list(nodes)
#TODO: if graph is bidirectional, need to explode here too
#TODO: how do we handle explode for multi graphs?
    for node in nodes:
        log.debug("Exploding from %s" % node)
        neighbors = graph.neighbors(node)
        neigh_edge_pairs = ( (s,t) for s in neighbors for t in neighbors if s != t)
        neigh_edge_pairs = list(neigh_edge_pairs)
        edges_to_add = []
        for (src, dst) in neigh_edge_pairs:
            src_to_node_data = dict( (key, graph[src][node][key]) for key in retain)
            node_to_dst_data = dict( (key, graph[node][dst][key]) for key in retain)

            # copy interfaces
            src_int_id = graph[src][node]["_interfaces"][src]
            dst_int_id = graph[node][dst]["_interfaces"][dst]
            src_to_node_data["_interfaces"] = {src: src_int_id, dst: dst_int_id}

            src_to_node_data.update(node_to_dst_data)
            #TODO: handle interfaces for explode
            edges_to_add.append((src, dst, src_to_node_data))

        graph.add_edges_from(edges_to_add)
        added_edges += edges_to_add

        graph.remove_node(node)
    return wrap_edges(OverlayGraph, added_edges)
Esempio n. 26
0
def connected_subgraphs(NmGraph, nodes):
    nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(NmGraph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):

        # print "Nothing to aggregate for %s: no edges in subgraph"

        pass
    if graph.is_directed():
        component_nodes_list = \
            nx.strongly_connected_components(subgraph)
    else:
        component_nodes_list = nx.connected_components(subgraph)

    wrapped = []
    for component in component_nodes_list:
        wrapped.append(list(wrap_nodes(NmGraph, component)))

    return wrapped
Esempio n. 27
0
File: ank.py Progetto: wilko77/STRIP
def aggregate_nodes(overlay_graph, nodes, retain = []):
    """Combines connected into a single node"""
    try:
        retain.lower()
        retain = [retain] # was a string, put into list
    except AttributeError:
        pass # already a list

    nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(overlay_graph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):
        #print "Nothing to aggregate for %s: no edges in subgraph"
        pass
    total_added_edges = []
    for component_nodes in nx.connected_components(subgraph):
        if len(component_nodes) > 1:
            base = component_nodes.pop() # choose one base device to retain
            nodes_to_remove = set(component_nodes) # remaining nodes, set for fast membership test
            external_edges = nx.edge_boundary(graph, component_nodes)
            edges_to_add = []
            for src, dst in external_edges:
                # src is the internal node to remove
                if src == base or dst == base:
                    continue # don't alter edges from base
                else:
                    if src in nodes_to_remove:
                        # edge from component to outside
                        data = dict( (key, graph[src][dst][key]) for key in retain)
                        edges_to_add.append((base, dst, data))
                    else:
                        # edge from outside into component
                        data = dict( (key, graph[dst][src][key]) for key in retain)
                        edges_to_add.append((base, src, data))
            graph.add_edges_from(edges_to_add)
            total_added_edges += edges_to_add
            graph.remove_nodes_from(nodes_to_remove)

    return wrap_edges(overlay_graph, total_added_edges)
Esempio n. 28
0
File: anm.py Progetto: wilko77/STRIP
    def _init_interfaces(self, nbunch = None):
        #TODO: make this more efficient by taking in the newly added node ids as a parameter
        if not nbunch:
            nbunch = [n for n in self._graph.nodes()]

        try:
            nbunch = list(unwrap_nodes(nbunch))
        except AttributeError:
            pass # don't need to unwrap

        phy_graph = self._anm._overlays["phy"]
        
        for node in nbunch:
            #TODO: tidy up this hardcoded logic
            try:
                phy_interfaces = phy_graph.node[node]["_interfaces"]
                data = dict( (key, {}) for key in phy_interfaces)
                self._graph.node[node]['_interfaces'] = data
            except KeyError:
# no counterpart in physical graph, initialise
                log.debug("Initialise interfaces for %s in %s" % (node, self._overlay_id))
                self._graph.node[node]['_interfaces'] = {0: {'description': 'loopback'}}
Esempio n. 29
0
def connected_subgraphs(nm_graph, nodes = None):
    """

    >>> anm = autonetkit.topos.house()
    >>> g_phy = anm['phy']
    >>> connected_subgraphs(g_phy)
    [[r4, r5, r1, r2, r3]]
    >>> edges = [("r2", "r4"), ("r3", "r5")]
    >>> g_phy.remove_edges_from(edges)
    >>> connected_subgraphs(g_phy)
    [[r1, r2, r3], [r4, r5]]


    """
    if nodes is None:
        nodes = nm_graph.nodes()
    else:
        nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(nm_graph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):

        # print "Nothing to aggregate for %s: no edges in subgraph"

        pass
    if graph.is_directed():
        component_nodes_list = \
            nx.strongly_connected_components(subgraph)
    else:
        component_nodes_list = nx.connected_components(subgraph)

    wrapped = []
    for component in component_nodes_list:
        wrapped.append(list(wrap_nodes(nm_graph, component)))

    return wrapped
Esempio n. 30
0
def aggregate_nodes(NmGraph, nodes, retain = []):
    """Combines connected into a single node"""
    try:
        retain.lower()
        retain = [retain] # was a string, put into list
    except AttributeError:
        pass # already a list

    nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(NmGraph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):
        #print "Nothing to aggregate for %s: no edges in subgraph"
        pass
    total_added_edges = []
    if graph.is_directed():
        component_nodes_list = nx.strongly_connected_components(subgraph)
    else:
        component_nodes_list = nx.connected_components(subgraph)
    for component_nodes in component_nodes_list:
        if len(component_nodes) > 1:
            base = component_nodes.pop() # choose one base device to retain
            nodes_to_remove = set(component_nodes) # remaining nodes, set for fast membership test
            external_edges = nx.edge_boundary(graph, component_nodes)
            edges_to_add = []
            for src, dst in external_edges:
                # src is the internal node to remove
                if src == base or dst == base:
                    continue # don't alter edges from base
                else:
                    if src in nodes_to_remove:
                        # edge from component to outside
                        interfaces = graph[src][dst]["_interfaces"]
                        dst_int_id = interfaces[dst]
                        data = dict( (key, graph[src][dst][key]) for key in retain)
                        data['_interfaces'] = {dst: dst_int_id}
                        edges_to_add.append((base, dst, data))
                        if graph.is_directed():
                            # other direction
                            #TODO: check which data should be copied
                            dst_data = dict( (key, graph[src][dst][key]) for key in retain)
                            dst_data['_interfaces'] = {dst: dst_int_id}
                            edges_to_add.append((dst, base, dst_data))
                    else:
                        # edge from outside into component
                        interfaces = graph[dst][src]["_interfaces"]
                        src_int_id = interfaces[src]
                        data = dict( (key, graph[dst][src][key]) for key in retain)
                        data['_interfaces'] = {src: src_int_id}
                        edges_to_add.append((base, src, data))
                        if graph.is_directed():
                            # other direction
                            #TODO: check which data should be copied
                            dst_data = dict( (key, graph[src][dst][key]) for key in retain)
                            dst_data['_interfaces'] = {src: src_int_id}
                            edges_to_add.append((src, base, dst_data))

            graph.add_edges_from(edges_to_add)
            total_added_edges += edges_to_add
            graph.remove_nodes_from(nodes_to_remove)

    return wrap_edges(NmGraph, total_added_edges)
Esempio n. 31
0
def aggregate_nodes(nm_graph, nodes, retain=None):
    """Combines connected into a single node"""
    if retain is None:
        retain = []

    try:
        retain.lower()
        retain = [retain]  # was a string, put into list
    except AttributeError:
        pass  # already a list

    nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(nm_graph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):

        # print "Nothing to aggregate for %s: no edges in subgraph"

        pass
    total_added_edges = []
    if graph.is_directed():
        component_nodes_list = \
            nx.strongly_connected_components(subgraph)
    else:
        component_nodes_list = nx.connected_components(subgraph)
    for component_nodes in component_nodes_list:
        if len(component_nodes) > 1:
            component_nodes = [nm_graph.node(n)
                               for n in component_nodes]

            # TODO: could choose most connected, or most central?
            # TODO: refactor so use nodes_to_remove

            nodes_to_remove = list(component_nodes)
            base = nodes_to_remove.pop()  # choose a base device to retain
            log.debug('Retaining %s, removing %s', base,
                      nodes_to_remove)

            external_edges = []
            for node in nodes_to_remove:
                external_edges += [e for e in node.edges() if e.dst
                                   not in component_nodes]
                # all edges out of component

            log.debug('External edges %s', external_edges)
            edges_to_add = []
            for edge in external_edges:
                dst = edge.dst
                data = dict((key, edge._data.get(key)) for key in
                            retain)
                ports = edge.raw_interfaces
                dst_int_id = ports[dst.node_id]

                # TODO: bind to (and maybe add) port on the new switch?

                data['_ports'] = {dst.node_id: dst_int_id}

                append = (base.node_id, dst.node_id, data)
                edges_to_add.append(append)

            nm_graph.add_edges_from(edges_to_add)
            total_added_edges += edges_to_add
            nm_graph.remove_nodes_from(nodes_to_remove)

    return wrap_edges(nm_graph, total_added_edges)
Esempio n. 32
0
def aggregate_nodes(OverlayGraph, nodes, retain = []):
    """Combines connected into a single node"""
    try:
        retain.lower()
        retain = [retain] # was a string, put into list
    except AttributeError:
        pass # already a list

    nodes = list(unwrap_nodes(nodes))
    graph = unwrap_graph(OverlayGraph)
    subgraph = graph.subgraph(nodes)
    if not len(subgraph.edges()):
        #print "Nothing to aggregate for %s: no edges in subgraph"
        pass
    total_added_edges = []
    if graph.is_directed():
        component_nodes_list = nx.strongly_connected_components(subgraph) 
    else:
        component_nodes_list = nx.connected_components(subgraph) 
    for component_nodes in component_nodes_list:
        if len(component_nodes) > 1:
            base = component_nodes.pop() # choose one base device to retain
            nodes_to_remove = set(component_nodes) # remaining nodes, set for fast membership test
            external_edges = nx.edge_boundary(graph, component_nodes)
            edges_to_add = []
            for src, dst in external_edges:
                # src is the internal node to remove
                if src == base or dst == base:
                    continue # don't alter edges from base
                else:
                    if src in nodes_to_remove:
                        # edge from component to outside
                        interfaces = graph[src][dst]["_interfaces"]
                        dst_int_id = interfaces[dst]
                        data = dict( (key, graph[src][dst][key]) for key in retain)
                        data['_interfaces'] = {dst: dst_int_id}
                        edges_to_add.append((base, dst, data))
                        if graph.is_directed():
                            # other direction
                            #TODO: check which data should be copied
                            dst_data = dict( (key, graph[src][dst][key]) for key in retain)
                            dst_data['_interfaces'] = {dst: dst_int_id}
                            edges_to_add.append((dst, base, dst_data))
                    else:
                        # edge from outside into component
                        interfaces = graph[dst][src]["_interfaces"]
                        src_int_id = interfaces[src]
                        data = dict( (key, graph[dst][src][key]) for key in retain)
                        data['_interfaces'] = {src: src_int_id}
                        edges_to_add.append((base, src, data))
                        if graph.is_directed():
                            # other direction
                            #TODO: check which data should be copied
                            dst_data = dict( (key, graph[src][dst][key]) for key in retain)
                            dst_data['_interfaces'] = {src: src_int_id}
                            edges_to_add.append((src, base, dst_data))
                        
            graph.add_edges_from(edges_to_add)
            total_added_edges += edges_to_add
            graph.remove_nodes_from(nodes_to_remove)

    return wrap_edges(OverlayGraph, total_added_edges)