Пример #1
0
    def run_unset(self, node_name):
        key = Consts.STATIC_PREFIX_ALLOC_PARAM_KEY

        # Retrieve previous allocation
        resp = self.client.get_keys([key])
        allocs = None
        if key in resp.keyVals:
            allocs = serializer.deserialize_thrift_object(
                resp.keyVals.get(key).value, alloc_types.StaticAllocation
            )
        else:
            allocs = alloc_types.StaticAllocation(nodePrefixes={node_name: ""})

        # Return if there need no change
        if node_name not in allocs.nodePrefixes:
            print("No changes needed. {}'s prefix is not set".format(node_name))

        # Update value in KvStore
        del allocs.nodePrefixes[node_name]
        value = serializer.serialize_thrift_object(allocs)
        self.run(key, value, "breeze", None, Consts.CONST_TTL_INF)
Пример #2
0
def build_global_prefix_db(resp):
    """ build a map of all prefixes in the network. this is used
        for checking for changes in topology

        :param resp kv_store_types.Publication: the parsed publication

        :return map(node, set([prefix])): the global prefix map,
            prefixes mapped to the node
    """

    # map: (node) -> set([prefix])
    global_prefix_db = {}

    for (key, value) in resp.keyVals.items():
        if not key.startswith(Consts.PREFIX_DB_MARKER):
            continue
        prefix_db = deserialize_thrift_object(value.value,
                                              lsdb_types.PrefixDatabase)
        update_global_prefix_db(global_prefix_db, prefix_db)

    return global_prefix_db
Пример #3
0
def build_global_adj_db(resp):
    """ build a map of all adjacencies in the network. this is used
        for bi-directional validation

        :param resp kv_store_types.Publication: the parsed publication

        :return map(node, AdjacencyDatabase): the global
            adj map, devices name mapped to devices it connects to, and
            properties of that connection
    """

    # map: (node) -> AdjacencyDatabase)
    global_adj_db = {}

    for (key, value) in resp.keyVals.items():
        if not key.startswith(Consts.ADJ_DB_MARKER):
            continue
        adj_db = deserialize_thrift_object(value.value, lsdb_types.AdjacencyDatabase)
        update_global_adj_db(global_adj_db, adj_db)

    return global_adj_db
Пример #4
0
    def print_db_delta_adj(self, key, value, kvstore_adj_node_names,
                           decision_adj_dbs, json):
        """Returns status code. 0 = success, 1 = failure"""

        kvstore_adj_db = deserialize_thrift_object(
            value.value, openr_types.AdjacencyDatabase)
        node_name = kvstore_adj_db.thisNodeName
        kvstore_adj_node_names.add(node_name)
        if node_name not in decision_adj_dbs:
            print(
                printing.render_vertical_table([[
                    "node {}'s adj db is missing in Decision".format(node_name)
                ]]))
            return 1
        decision_adj_db = decision_adj_dbs[node_name]

        return_code = 0
        if json:
            tags = ("in_decision", "in_kvstore",
                    "changed_in_decision_and_kvstore")
            adj_list_deltas = utils.find_adj_list_deltas(
                decision_adj_db.adjacencies,
                kvstore_adj_db.adjacencies,
                tags=tags)
            deltas_json, return_code = utils.adj_list_deltas_json(
                adj_list_deltas, tags=tags)
            if return_code:
                utils.print_json(deltas_json)
        else:
            lines = utils.sprint_adj_db_delta(kvstore_adj_db, decision_adj_db)
            if lines:
                print(
                    printing.render_vertical_table([[
                        "node {}'s adj db in Decision out of sync with "
                        "KvStore's".format(node_name)
                    ]]))
                print("\n".join(lines))
                return_code = 1

        return return_code
Пример #5
0
def interface_db_to_dict(value):
    '''
    Convert a thrift::Value representation of InterfaceDatabase to bunch
    object
    '''

    def _parse_intf_info(info):
        return bunch.Bunch(**{
            'isUp': info.isUp,
            'ifIndex': info.ifIndex,
            'v4Addrs': [sprint_addr(v.addr) for v in info.v4Addrs],
            'v6Addrs': [sprint_addr(v.addr) for v in info.v6LinkLocalAddrs],
        })

    assert(isinstance(value, kv_store_types.Value))
    intf_db = deserialize_thrift_object(value.value,
                                        lsdb_types.InterfaceDatabase)
    return bunch.Bunch(**{
        'thisNodeName': intf_db.thisNodeName,
        'interfaces': {k: _parse_intf_info(v)
                       for k, v in intf_db.interfaces.items()},
    })
Пример #6
0
    def get_connected_nodes(self, adj_keys: openr_types.Publication,
                            node_id: str) -> Set[str]:
        """
        Build graph of adjacencies and return list of connected node from
        current node-id
        """
        import networkx as nx

        edges = set()
        graph = nx.Graph()
        for adj_value in adj_keys.keyVals.values():
            adj_db = serializer.deserialize_thrift_object(
                adj_value.value, openr_types.AdjacencyDatabase)
            graph.add_node(adj_db.thisNodeName)
            for adj in adj_db.adjacencies:
                # Add edge only when we see the reverse side of it.
                if (adj.otherNodeName, adj_db.thisNodeName,
                        adj.otherIfName) in edges:
                    graph.add_edge(adj.otherNodeName, adj_db.thisNodeName)
                    continue
                edges.add((adj_db.thisNodeName, adj.otherNodeName, adj.ifName))
        return nx.node_connected_component(graph, node_id)
Пример #7
0
    def print_adj_delta(self, key, value, delta, global_adj_db,
                        global_publication_db):
        _, reported_node_name = key.split(':', 1)
        new_adj_db = deserialize_thrift_object(value.value,
                                               lsdb_types.AdjacencyDatabase)
        if delta:
            old_adj_db = global_adj_db.get(new_adj_db.thisNodeName, None)
            if old_adj_db is None:
                lines = ["ADJ_DB_ADDED: {}".format(new_adj_db.thisNodeName)]
            else:
                lines = utils.sprint_adj_db_delta(new_adj_db, old_adj_db)
                lines = '\n'.join(lines)
        else:
            _, lines = utils.sprint_adj_db_full(global_adj_db, new_adj_db,
                                                False)

        if lines:
            print_publication_delta(
                "{}'s adjacencies".format(reported_node_name),
                utils.sprint_pub_update(global_publication_db, key, value),
                lines)

        utils.update_global_adj_db(global_adj_db, new_adj_db)
Пример #8
0
    def print_prefix_delta(
        self, key, value, delta, global_prefix_db, global_publication_db
    ):
        _, reported_node_name = key.split(":", 1)
        prefix_db = serializer.deserialize_thrift_object(
            value.value, lsdb_types.PrefixDatabase
        )
        if delta:
            lines = "\n".join(
                utils.sprint_prefixes_db_delta(global_prefix_db, prefix_db)
            )
        else:
            lines = utils.sprint_prefixes_db_full(prefix_db)

        if lines:
            print_timestamp()
            print_publication_delta(
                "{}'s prefixes".format(reported_node_name),
                utils.sprint_pub_update(global_publication_db, key, value),
                lines,
            )

        utils.update_global_prefix_db(global_prefix_db, prefix_db)
Пример #9
0
    def run_set(self, node_name, prefix_str):
        key = Consts.STATIC_PREFIX_ALLOC_PARAM_KEY
        prefix = utils.ip_str_to_prefix(prefix_str)

        # Retrieve previous allocation
        resp = self.client.get_keys([key])
        allocs = None
        if key in resp.keyVals:
            allocs = serializer.deserialize_thrift_object(
                resp.keyVals.get(key).value, alloc_types.StaticAllocation)
        else:
            allocs = alloc_types.StaticAllocation(nodePrefixes={})

        # Return if there is no change
        if allocs.nodePrefixes.get(node_name) == prefix:
            print('No changes needed. {}\'s prefix is already set to {}'
                  .format(node_name, prefix_str))
            return

        # Update value in KvStore
        allocs.nodePrefixes[node_name] = prefix
        value = serializer.serialize_thrift_object(allocs)
        self.run(key, value, 'breeze', None, Consts.CONST_TTL_INF)
Пример #10
0
    def send_and_recv_thrift_obj(self, thrift_obj_to_send, thrift_type_to_recv):
        req = serializer.serialize_thrift_object(
            thrift_obj_to_send, self.cli_opts.proto_factory
        )

        resp = None
        if self.thrift_client:
            try:
                resp = self.thrift_client.command(self.module_type, req)
            except Exception as e:
                print(
                    "Tried to connect via thrift but could not. Exception: "
                    "{}".format(e),
                    file=sys.stderr,
                )
                self.cleanup_thrift()
                raise e
        else:
            try:
                self.zmq_client.send(req)
                resp = self.zmq_client.recv()
            # TODO: remove after Link monitor socket is changed to ROUTER everywhere
            except Exception as e:
                if OpenrModuleType.LINK_MONITOR == self.module_type:
                    dealer_client = self.get_zmq_client(zmq.DEALER)
                    dealer_client.send(req)
                    resp = dealer_client.recv()
                else:
                    raise e

        if thrift_type_to_recv is str:
            return str(resp)

        return serializer.deserialize_thrift_object(
            resp, thrift_type_to_recv, self.cli_opts.proto_factory
        )
Пример #11
0
    def print_db_delta(
        self,
        key,
        value,
        kvstore_adj_node_names,
        kvstore_prefix_node_names,
        decision_adj_dbs,
        decision_prefix_dbs,
        json,
    ):
        """ Returns status code. 0 = success, 1 = failure"""

        if key.startswith(Consts.ADJ_DB_MARKER):
            kvstore_adj_db = deserialize_thrift_object(
                value.value, lsdb_types.AdjacencyDatabase
            )
            node_name = kvstore_adj_db.thisNodeName
            kvstore_adj_node_names.add(node_name)
            if node_name not in decision_adj_dbs:
                print(
                    printing.render_vertical_table(
                        [["node {}'s adj db is missing in Decision".format(node_name)]]
                    )
                )
                return 1
            decision_adj_db = decision_adj_dbs[node_name]

            return_code = 0
            if json:
                tags = ("in_decision", "in_kvstore", "changed_in_decision_and_kvstore")
                adj_list_deltas = utils.find_adj_list_deltas(
                    decision_adj_db.adjacencies, kvstore_adj_db.adjacencies, tags=tags
                )
                deltas_json, return_code = utils.adj_list_deltas_json(
                    adj_list_deltas, tags=tags
                )
                if return_code:
                    utils.print_json(deltas_json)
            else:
                lines = utils.sprint_adj_db_delta(kvstore_adj_db, decision_adj_db)
                if lines:
                    print(
                        printing.render_vertical_table(
                            [
                                [
                                    "node {}'s adj db in Decision out of sync with "
                                    "KvStore's".format(node_name)
                                ]
                            ]
                        )
                    )
                    print("\n".join(lines))
                    return_code = 1

            return return_code

        if key.startswith(Consts.PREFIX_DB_MARKER):
            kvstore_prefix_db = deserialize_thrift_object(
                value.value, lsdb_types.PrefixDatabase
            )
            node_name = kvstore_prefix_db.thisNodeName
            kvstore_prefix_node_names.add(node_name)
            if node_name not in decision_prefix_dbs:
                print(
                    printing.render_vertical_table(
                        [
                            [
                                "node {}'s prefix db is missing in Decision".format(
                                    node_name
                                )
                            ]
                        ]
                    )
                )
                return 1
            decision_prefix_db = decision_prefix_dbs[node_name]
            decision_prefix_set = {}
            utils.update_global_prefix_db(decision_prefix_set, decision_prefix_db)
            lines = utils.sprint_prefixes_db_delta(
                decision_prefix_set, kvstore_prefix_db
            )
            if lines:
                print(
                    printing.render_vertical_table(
                        [
                            [
                                "node {}'s prefix db in Decision out of sync with "
                                "KvStore's".format(node_name)
                            ]
                        ]
                    )
                )
                print("\n".join(lines))
                return 1

            return 0
Пример #12
0
 def _parse_nodes(node_dict, value):
     prefix_db = deserialize_thrift_object(value.value,
                                           lsdb_types.PrefixDatabase)
     node_dict[prefix_db.thisNodeName] = self.get_node_ip(prefix_db)
Пример #13
0
 def _parse_nodes(node_set, value):
     prefix_db = deserialize_thrift_object(
         value.value, lsdb_types.PrefixDatabase)
     node_set.add(prefix_db.thisNodeName)
Пример #14
0
 def _run(self, client: OpenrCtrl.Client) -> None:
     prefix_mgr_config_blob = client.getConfigKey(Consts.PREFIX_MGR_KEY)
     prefix_mgr_config = deserialize_thrift_object(
         prefix_mgr_config_blob, lsdb_types.PrefixDatabase)
     self.print_config(prefix_mgr_config)
Пример #15
0
 def _run(self, client: OpenrCtrl.Client) -> None:
     lm_config_blob = client.getConfigKey(Consts.LINK_MONITOR_KEY)
     lm_config = deserialize_thrift_object(lm_config_blob,
                                           lm_types.LinkMonitorConfig)
     self.print_config(lm_config)
Пример #16
0
 def _run(self, client: OpenrCtrl.Client):
     prefix_alloc_blob = client.getConfigKey(Consts.PREFIX_ALLOC_KEY)
     prefix_alloc = deserialize_thrift_object(prefix_alloc_blob,
                                              ap_types.AllocPrefix)
     self.print_config(prefix_alloc)