def __init__(self, *args, **kwargs):
     super(SouthboundListener, self).__init__(*args, **kwargs)
     self.igp_graph = IGPGraph()
     self.dirty = False
     self.json_proxy = SJMPClient(hostname=CFG.get(DEFAULTSECT,
                                                   'json_hostname'),
                                  port=CFG.getint(DEFAULTSECT, 'json_port'),
                                  target=self)
     self.quagga_manager = ProxyCloner(FakeNodeProxy, self.json_proxy)
 def __init__(self, *args, **kwargs):
     super(SouthboundListener, self).__init__(*args, **kwargs)
     self.igp_graph = IGPGraph()
     self.dirty = False
     self.json_proxy = SJMPClient(hostname=CFG.get(DEFAULTSECT,
                                                   'json_hostname'),
                                  port=CFG.getint(DEFAULTSECT, 'json_port'),
                                  target=self)
     self.quagga_manager = ProxyCloner(FakeNodeProxy, self.json_proxy)
Пример #3
0
 def __init__(self, fwd_dags, optimizer, additional_routes=None):
     self.igp_graph = nx.DiGraph()
     self.dirty = False
     self.additional_routes = additional_routes
     self.optimizer = optimizer
     self.fwd_dags = fwd_dags
     self.current_lsas = set([])
     self.json_proxy = SJMPClient(hostname=CFG.get(DEFAULTSECT,
                                                   'json_hostname'),
                                  port=CFG.getint(DEFAULTSECT, 'json_port'),
                                  target=self)
     self.quagga_manager = ProxyCloner(FakeNodeProxy, self.json_proxy)
    def __init__(self, client, *args, **kwargs):
        Cmd.__init__(self, *args, **kwargs)
        self.client = client

    def do_add(self, line=''):
        self.client.add(('192.168.14.1', '192.168.23.2', 1, '3.3.3.0/24'))
        self.client.add((None, '192.168.23.2', 1, '4.4.4.0/24'))
        self.client.add([(None, '192.168.23.2', 1, '5.5.5.0/24'),
                         (None, '192.168.14.1', 1, '5.5.5.0/24')])

    def do_remove(self, line=''):
        self.client.remove(('192.168.14.1', '192.168.23.2', '3.3.3.0/24'))
        self.client.remove((None, '192.168.23.2', '4.4.4.0/24'))
        self.client.remove([(None, '192.168.23.2', '5.5.5.0/24'),
                            (None, '192.168.14.1', '5.5.5.0/24')])

    def do_exit(self, line):
            return True

if __name__ == '__main__':
    log.setLevel(logging.DEBUG)
    shapeshifter = ShapeshifterProxyTest()
    c = SJMPClient("localhost",
                   CFG.getint(DEFAULTSECT, "json_port"),
                   target=shapeshifter)
    fakenode = ProxyCloner(FakeNodeProxy, c)
    Thread(target=c.communicate, name='client').start()
    TestCLI(fakenode).cmdloop()
    c.stop()
class SouthboundListener(ShapeshifterProxy):
    """This basic controller maintains a structure describing the IGP topology
    and listens for changes."""

    def __init__(self, *args, **kwargs):
        super(SouthboundListener, self).__init__(*args, **kwargs)
        self.igp_graph = IGPGraph()
        self.dirty = False
        self.json_proxy = SJMPClient(hostname=CFG.get(DEFAULTSECT,
                                                      'json_hostname'),
                                     port=CFG.getint(DEFAULTSECT, 'json_port'),
                                     target=self)
        self.quagga_manager = ProxyCloner(FakeNodeProxy, self.json_proxy)

    def run(self):
        """Connect the the southbound controller. This call will not return
        unless the connection is halted."""
        log.info('Connecting to server ...')
        self.json_proxy.communicate()

    def stop(self):
        """Stop the connection to the southbound controller"""
        self.json_proxy.stop()

    def bootstrap_graph(self, graph, node_properties):
        self.igp_graph.clear()
        self.igp_graph.add_edges_from(graph)
        for _, _, d in self.igp_graph.edges_iter(data=True):
            sanitize_edge_data(d)
        self.update_node_properties(**node_properties)
        log.debug('Bootstrapped graph with edges: %s and properties: %s',
                  self.igp_graph.edges(data=True), node_properties)
        self.received_initial_graph()
        self.graph_changed()

    def received_initial_graph(self):
        """Called when the initial graph has been bootstrapped, before
        calling graph_changed"""
        pass

    def add_edge(self, source, destination, properties={'metric': 1}):
        properties = sanitize_edge_data(properties)
        # metric is added twice to support backward-compat.
        self.igp_graph.add_edge(source, destination, properties)
        log.debug('Added edge: %s-%s@%s', source, destination, properties)
        # Only trigger an update if the link is bidirectional
        self.dirty = self.igp_graph.has_edge(destination, source)

    def commit(self):
        log.debug('End of graph update')
        if self.dirty:
            self.dirty = False
            self.graph_changed()

    @abc.abstractmethod
    def graph_changed(self):
        """Called when the IGP graph has changed."""

    def remove_edge(self, source, destination):
        # TODO: pay attention to re-add the symmetric edge if only one way
        # crashed
        try:
            self.igp_graph.remove_edge(source, destination)
            log.debug('Removed edge %s-%s', source, destination)
            self.igp_graph.remove_edge(destination, source)
            log.debug('Removed edge %s-%s', destination, source)
        except nx.NetworkXError:
            # This means that we had already removed both side of the edge
            # earlier or that the adjacency was not fully established before
            # going down
            pass
        else:
            self.dirty = True

    def update_node_properties(self, **properties):
        log.debug('Updating node propeties: %s', properties)
        for node, data in properties.iteritems():
            self.igp_graph.node[node].update(data)
        self.dirty = self.dirty or properties
class SouthboundListener(ShapeshifterProxy):
    """This basic controller maintains a structure describing the IGP topology
    and listens for changes."""

    def __init__(self, *args, **kwargs):
        super(SouthboundListener, self).__init__(*args, **kwargs)
        self.igp_graph = IGPGraph()
        self.dirty = False
        self.json_proxy = SJMPClient(hostname=CFG.get(DEFAULTSECT,
                                                      'json_hostname'),
                                     port=CFG.getint(DEFAULTSECT, 'json_port'),
                                     target=self)
        self.quagga_manager = ProxyCloner(FakeNodeProxy, self.json_proxy)

    def run(self):
        """Connect the the southbound controller. This call will not return
        unless the connection is halted."""
        log.info('Connecting to server ...')
        self.json_proxy.communicate()

    def stop(self):
        """Stop the connection to the southbound controller"""
        self.json_proxy.stop()

    def bootstrap_graph(self, graph, node_properties):
        self.igp_graph.clear()
        self.igp_graph.add_edges_from(graph)
        for _, _, d in self.igp_graph.edges_iter(data=True):
            sanitize_edge_data(d)
        self.update_node_properties(**node_properties)
        log.debug('Bootstrapped graph with edges: %s and properties: %s',
                  self.igp_graph.edges(data=True), node_properties)
        self.received_initial_graph()
        self.graph_changed()

    def received_initial_graph(self):
        """Called when the initial graph has been bootstrapped, before
        calling graph_changed"""
        pass

    def add_edge(self, source, destination, properties={'metric': 1}):
        properties = sanitize_edge_data(properties)
        # metric is added twice to support backward-compat.
        self.igp_graph.add_edge(source, destination, properties)
        log.debug('Added edge: %s-%s@%s', source, destination, properties)
        # Only trigger an update if the link is bidirectional
        self.dirty = self.igp_graph.has_edge(destination, source)

    def commit(self):
        log.debug('End of graph update')
        if self.dirty:
            self.dirty = False
            self.graph_changed()

    @abc.abstractmethod
    def graph_changed(self):
        """Called when the IGP graph has changed."""

    def remove_edge(self, source, destination):
        # TODO: pay attention to re-add the symmetric edge if only one way
        # crashed
        try:
            self.igp_graph.remove_edge(source, destination)
            log.debug('Removed edge %s-%s', source, destination)
            self.igp_graph.remove_edge(destination, source)
            log.debug('Removed edge %s-%s', destination, source)
        except nx.NetworkXError:
            # This means that we had already removed both side of the edge
            # earlier or that the adjacency was not fully established before
            # going down
            pass
        else:
            self.dirty = True

    def update_node_properties(self, **properties):
        log.debug('Updating node propeties: %s', properties)
        for node, data in properties.iteritems():
            self.igp_graph.node[node].update(data)
        self.dirty = self.dirty or properties
Пример #7
0
class SouthboundManager(ShapeshifterProxy):
    def __init__(self, fwd_dags, optimizer, additional_routes=None):
        self.igp_graph = nx.DiGraph()
        self.dirty = False
        self.additional_routes = additional_routes
        self.optimizer = optimizer
        self.fwd_dags = fwd_dags
        self.current_lsas = set([])
        self.json_proxy = SJMPClient(hostname=CFG.get(DEFAULTSECT,
                                                      'json_hostname'),
                                     port=CFG.getint(DEFAULTSECT, 'json_port'),
                                     target=self)
        self.quagga_manager = ProxyCloner(FakeNodeProxy, self.json_proxy)

    def run(self):
        log.info('Connecting to server ...')
        self.json_proxy.communicate()

    def stop(self):
        self.quagga_manager.remove(list(self.current_lsas))
        self.json_proxy.stop()

    # Helper functions
    def _refresh_augmented_topo(self):
        log.info('Solving topologies')
        self.optimizer.solve(self.igp_graph,
                             self.fwd_dags)

    def _get_diff_lsas(self):
        self._refresh_augmented_topo()
        new_lsas = set(self.optimizer.get_fake_lsas())
        log.info('New LSA set: %s', new_lsas)
        to_add = new_lsas.difference(self.current_lsas)
        to_rem = self.current_lsas.difference(new_lsas)
        log.info('Removing LSA set: %s', to_rem)
        self.current_lsas = new_lsas
        return to_add, to_rem

    def _refresh_lsas(self):
        (to_add, to_rem) = self._get_diff_lsas()
        if to_rem:
            self.quagga_manager.remove(list(to_rem))
        if to_add:
            self.quagga_manager.add(list(to_add))

    # Interface functions
    def boostrap_graph(self, graph):
        self.igp_graph.clear()
        for u, v, metric in graph:
            self.igp_graph.add_edge(u, v, weight=int(metric))
        log.debug('Bootstrapped graph with edges: %s', self.igp_graph.edges())
        log.debug('Sending initial lsa''s')
        if self.additional_routes:
            self.quagga_manager.add_static(self.additional_routes)
        self._refresh_lsas()

    def add_edge(self, source, destination, metric):
        self.igp_graph.add_edge(source, destination, weight=int(metric))
        log.debug('Added edge: %s-%s@%s', source, destination, metric)
        try:
            self.igp_graph[destination][source]
        except KeyError:
            # Only trigger an update if the link is bidirectional
            pass
        else:
            self.dirty = True

    def commit(self):
        if self.dirty:
            self._refresh_lsas()
            self.dirty = False

    def remove_edge(self, source, destination):
        # TODO: pay attention to re-add the symmetric edge if only one way
        # crashed
        try:
            self.igp_graph.remove_edge(source, destination)
            log.debug('Removed edge %s-%s', source, destination)
            self.igp_graph.remove_edge(destination, source)
            log.debug('Removed edge %s-%s', destination, source)
        except nx.NetworkXError:
            # This means that we had already removed both side of the edge
            # earlier
            pass
        else:
            self.dirty = True
Пример #8
0
class TestCLI(Cmd):
    Cmd.prompt = "> "

    def __init__(self, client, *args, **kwargs):
        Cmd.__init__(self, *args, **kwargs)
        self.client = client

    def do_add(self, line=""):
        self.client.add(("192.168.14.1", "192.168.23.2", 1, "3.3.3.0/24"))
        self.client.add((None, "192.168.23.2", 1, "4.4.4.0/24"))
        self.client.add([(None, "192.168.23.2", 1, "5.5.5.0/24"), (None, "192.168.14.1", 1, "5.5.5.0/24")])

    def do_remove(self, line=""):
        self.client.remove(("192.168.14.1", "192.168.23.2", "3.3.3.0/24"))
        self.client.remove((None, "192.168.23.2", "4.4.4.0/24"))
        self.client.remove([(None, "192.168.23.2", "5.5.5.0/24"), (None, "192.168.14.1", "5.5.5.0/24")])

    def do_exit(self, line):
        return True


if __name__ == "__main__":
    log.setLevel(logging.DEBUG)
    shapeshifter = ShapeshifterProxyTest()
    c = SJMPClient("localhost", CFG.getint(DEFAULTSECT, "json_port"), target=shapeshifter)
    fakenode = ProxyCloner(FakeNodeProxy, c)
    Thread(target=c.communicate, name="client").start()
    TestCLI(fakenode).cmdloop()
    c.stop()
Пример #9
0
    def do_exit(self, line):
        return True

    def do_info(self, line):
        # Query the remopte end for the supported methods/docs/args
        self.client.ask_info()

    def default(self, line):
        items = line.split(' ')
        self.client.execute(items[0], *items[1:])

if __name__ == '__main__':
    log.setLevel(logging.DEBUG)
    s = SJMPServer(H, P, target=EchoProxy())
    c = SJMPClient(H, P)
    a = ProxyCloner(EchoProxy, c)
    log.debug(dir(a))
    st = Thread(target=s.communicate, name='server')
    st.daemon = True
    st.start()
    log.debug('Started server')
    ct = Thread(target=c.communicate, name='client')
    ct.daemon = True
    ct.start()
    log.debug('Started client')
    a.echo('hello world')
    a.sum(1, 2)
    TestCLI(c).cmdloop()
    c.stop()
    s.stop()