def main(params): os.makedirs(params['dest_dir'], exist_ok=True) nodes_fn = os.path.join(params['dest_dir'], 'nodes.json') graph_fn = os.path.join(params['dest_dir'], 'graph.json') nodelist_fn = os.path.join(params['dest_dir'], 'nodelist.json') now = datetime.utcnow().replace(microsecond=0) # parse mesh param and instantiate Alfred/Batman instances alfred_instances = [] batman_instances = [] for value in params['mesh']: # (1) only batman-adv if, no alfred sock if ':' not in value: if len(params['mesh']) > 1: raise ValueError( 'Multiple mesh interfaces require the use of ' 'alfred socket paths.') alfred_instances.append(Alfred(unix_sockpath=None)) batman_instances.append(Batman(mesh_interface=value)) else: # (2) batman-adv if + alfred socket try: batif, alfredsock = value.split(':') alfred_instances.append(Alfred(unix_sockpath=alfredsock)) batman_instances.append(Batman(mesh_interface=batif, alfred_sockpath=alfredsock)) except ValueError: raise ValueError( 'Unparseable value "{0}" in --mesh parameter.'. format(value)) # read nodedb state from node.json try: with open(nodes_fn, 'r') as nodedb_handle: nodedb = json.load(nodedb_handle) except IOError: nodedb = {'nodes': dict()} # flush nodedb if it uses the old format if 'links' in nodedb: nodedb = {'nodes': dict()} # set version we're going to output nodedb['version'] = NODES_VERSION # update timestamp and assume all nodes are offline nodedb['timestamp'] = now.isoformat() for node_id, node in nodedb['nodes'].items(): node['flags']['online'] = False # integrate alfred nodeinfo for alfred in alfred_instances: nodeinfo = validate_nodeinfos(alfred.nodeinfo()) nodes.import_nodeinfo(nodedb['nodes'], nodeinfo, now, assume_online=True) # integrate static aliases data for aliases in params['aliases']: with open(aliases, 'r') as f: nodeinfo = validate_nodeinfos(json.load(f)) nodes.import_nodeinfo(nodedb['nodes'], nodeinfo, now, assume_online=False) nodes.reset_statistics(nodedb['nodes']) for alfred in alfred_instances: nodes.import_statistics(nodedb['nodes'], alfred.statistics()) # acquire gwl and visdata for each batman instance mesh_info = [] for batman in batman_instances: vd = batman.vis_data() gwl = batman.gateway_list() mesh_info.append((vd, gwl)) # update nodedb from batman-adv data for vd, gwl in mesh_info: nodes.import_mesh_ifs_vis_data(nodedb['nodes'], vd) nodes.import_vis_clientcount(nodedb['nodes'], vd) nodes.mark_vis_data_online(nodedb['nodes'], vd, now) nodes.mark_gateways(nodedb['nodes'], gwl) # clear the nodedb from nodes that have not been online in $prune days if params['prune']: nodes.prune_nodes(nodedb['nodes'], now, params['prune']) # build nxnetworks graph from nodedb and visdata batadv_graph = nx.DiGraph() for vd, gwl in mesh_info: graph.import_vis_data(batadv_graph, nodedb['nodes'], vd) # force mac addresses to be vpn-link only (like gateways for example) if params['vpn']: graph.mark_vpn(batadv_graph, frozenset(params['vpn'])) def extract_tunnel(nodes): macs = set() for id, node in nodes.items(): try: for mac in node["nodeinfo"]["network"]["mesh"]["bat0"]["interfaces"]["tunnel"]: macs.add(mac) except KeyError: pass return macs graph.mark_vpn(batadv_graph, extract_tunnel(nodedb['nodes'])) batadv_graph = graph.merge_nodes(batadv_graph) batadv_graph = graph.to_undirected(batadv_graph) # write processed data to dest dir with open(nodes_fn + '.tmp', 'w') as f: json.dump(nodedb, f) # prevent glitch if files is reading while the new content is writing f.flush() # From Python-Docs: first do f.flush() os.fsync(f.fileno()) # and then do os.fsync(f.fileno()) # to ensure that all internal buffers associated with f are written to disk. os.rename(nodes_fn + '.tmp', nodes_fn) # move new file to real position graph_out = {'batadv': json_graph.node_link_data(batadv_graph), 'version': GRAPH_VERSION} with open(graph_fn + '.tmp', 'w') as f: json.dump(graph_out, f) # prevent glitch if files is reading while the new content is writing f.flush() # From Python-Docs: first do f.flush() os.fsync(f.fileno()) # and then do os.fsync(f.fileno()) # to ensure that all internal buffers associated with f are written to disk. os.rename(graph_fn + '.tmp', graph_fn) # move new file to real position with open(nodelist_fn + '.tmp', 'w') as f: json.dump(export_nodelist(now, nodedb), f) # prevent glitch if files is reading while the new content is writing f.flush() # From Python-Docs: first do f.flush() os.fsync(f.fileno()) # and then do os.fsync(f.fileno()) # to ensure that all internal buffers associated with f are written to disk. os.rename(nodelist_fn + '.tmp', nodelist_fn) # move new file to real position # optional rrd graphs (trigger with --rrd) if params['rrd']: script_directory = os.path.dirname(os.path.realpath(__file__)) rrd = RRD(os.path.join(script_directory, 'nodedb'), os.path.join(params['dest_dir'], 'nodes')) rrd.update_database(nodedb['nodes']) rrd.update_images()
def main(params): os.makedirs(params['dest_dir'], exist_ok=True) nodes_fn = os.path.join(params['dest_dir'], 'nodes.json') graph_fn = os.path.join(params['dest_dir'], 'graph.json') nodelist_fn = os.path.join(params['dest_dir'], 'nodelist.json') now = datetime.utcnow().replace(microsecond=0) # parse mesh param and instantiate Alfred/Batman instances alfred_instances = [] batman_instances = [] for value in params['mesh']: # (1) only batman-adv if, no alfred sock if ':' not in value: if len(params['mesh']) > 1: raise ValueError('Multiple mesh interfaces require the use of ' 'alfred socket paths.') alfred_instances.append(Alfred(unix_sockpath=None)) batman_instances.append(Batman(mesh_interface=value)) else: # (2) batman-adv if + alfred socket try: batif, alfredsock = value.split(':') alfred_instances.append(Alfred(unix_sockpath=alfredsock)) batman_instances.append( Batman(mesh_interface=batif, alfred_sockpath=alfredsock)) except ValueError: raise ValueError( 'Unparseable value "{0}" in --mesh parameter.'.format( value)) # read nodedb state from node.json try: with open(nodes_fn, 'r') as nodedb_handle: nodedb = json.load(nodedb_handle) except IOError: nodedb = {'nodes': dict()} # flush nodedb if it uses the old format if 'links' in nodedb: nodedb = {'nodes': dict()} # set version we're going to output nodedb['version'] = NODES_VERSION # update timestamp and assume all nodes are offline nodedb['timestamp'] = now.isoformat() for node_id, node in nodedb['nodes'].items(): node['flags']['online'] = False # integrate alfred nodeinfo for alfred in alfred_instances: nodes.import_nodeinfo(nodedb['nodes'], alfred.nodeinfo(), now, assume_online=True) # integrate static aliases data for aliases in params['aliases']: with open(aliases, 'r') as f: nodes.import_nodeinfo(nodedb['nodes'], json.load(f), now, assume_online=False) nodes.reset_statistics(nodedb['nodes']) for alfred in alfred_instances: nodes.import_statistics(nodedb['nodes'], alfred.statistics()) # acquire gwl and visdata for each batman instance mesh_info = [] for batman in batman_instances: vd = batman.vis_data() gwl = batman.gateway_list() mesh_info.append((vd, gwl)) # update nodedb from batman-adv data for vd, gwl in mesh_info: nodes.import_mesh_ifs_vis_data(nodedb['nodes'], vd) nodes.import_vis_clientcount(nodedb['nodes'], vd) nodes.mark_vis_data_online(nodedb['nodes'], vd, now) nodes.mark_gateways(nodedb['nodes'], gwl) # clear the nodedb from nodes that have not been online in $prune days if params['prune']: nodes.prune_nodes(nodedb['nodes'], now, params['prune']) # build nxnetworks graph from nodedb and visdata batadv_graph = nx.DiGraph() for vd, gwl in mesh_info: graph.import_vis_data(batadv_graph, nodedb['nodes'], vd) # force mac addresses to be vpn-link only (like gateways for example) if params['vpn']: graph.mark_vpn(batadv_graph, frozenset(params['vpn'])) batadv_graph = graph.merge_nodes(batadv_graph) batadv_graph = graph.to_undirected(batadv_graph) # write processed data to dest dir with open(nodes_fn, 'w') as f: json.dump(nodedb, f) graph_out = { 'batadv': json_graph.node_link_data(batadv_graph), 'version': GRAPH_VERSION } with open(graph_fn, 'w') as f: json.dump(graph_out, f) with open(nodelist_fn, 'w') as f: json.dump(export_nodelist(now, nodedb), f) # optional rrd graphs (trigger with --rrd) if params['rrd']: script_directory = os.path.dirname(os.path.realpath(__file__)) rrd = RRD(os.path.join(script_directory, 'nodedb'), os.path.join(params['dest_dir'], 'nodes')) rrd.update_database(nodedb['nodes']) rrd.update_images()
def main(params): os.makedirs(params['dest_dir'], exist_ok=True) nodes_fn = os.path.join(params['dest_dir'], 'nodes.json') graph_fn = os.path.join(params['dest_dir'], 'graph.json') nodelist_fn = os.path.join(params['dest_dir'], 'nodelist.json') now = datetime.utcnow().replace(microsecond=0) # parse mesh param and instantiate Alfred/Batman instances alfred_instances = [] batman_instances = [] for value in params['mesh']: # (1) only batman-adv if, no alfred sock if ':' not in value: if len(params['mesh']) > 1: raise ValueError( 'Multiple mesh interfaces require the use of ' 'alfred socket paths.') alfred_instances.append(Alfred(unix_sockpath=None)) batman_instances.append(Batman(mesh_interface=value)) else: # (2) batman-adv if + alfred socket try: batif, alfredsock = value.split(':') alfred_instances.append(Alfred(unix_sockpath=alfredsock)) batman_instances.append(Batman(mesh_interface=batif, alfred_sockpath=alfredsock)) except ValueError: raise ValueError( 'Unparseable value "{0}" in --mesh parameter.'. format(value)) # read nodedb state from node.json try: with open(nodes_fn, 'r', encoding=('UTF-8')) as nodedb_handle: nodedb = json.load(nodedb_handle) except IOError: nodedb = {'nodes': []} # set version we're going to output nodedb['version'] = NODES_VERSION # update timestamp and assume all nodes are offline nodedb['timestamp'] = now.isoformat() for node in nodedb['nodes']: node['flags']['online'] = False nodesdict = {} for node in nodedb['nodes']: nodesdict[node['nodeinfo']['node_id']] = node # integrate alfred nodeinfo for alfred in alfred_instances: nodeinfo = validate_nodeinfos(alfred.nodeinfo()) nodes.import_nodeinfo(nodesdict, nodeinfo, now, assume_online=True) # integrate static aliases data for aliases in params['aliases']: with open(aliases, 'r') as f: nodeinfo = validate_nodeinfos(json.load(f)) nodes.import_nodeinfo(nodesdict, nodeinfo, now, assume_online=False) nodes.reset_statistics(nodesdict) for alfred in alfred_instances: nodes.import_statistics(nodesdict, alfred.statistics()) # acquire visdata for each batman instance mesh_info = [] for batman in batman_instances: vd = batman.vis_data() mesh_info.append(vd) # update nodedb from batman-adv data for vd in mesh_info: nodes.import_mesh_ifs_vis_data(nodesdict, vd) nodes.import_vis_clientcount(nodesdict, vd) nodes.mark_vis_data_online(nodesdict, vd, now) # clear the nodedb from nodes that have not been online in $prune days if params['prune']: nodes.prune_nodes(nodesdict, now, params['prune']) # build nxnetworks graph from nodedb and visdata batadv_graph = nx.DiGraph() for vd in mesh_info: graph.import_vis_data(batadv_graph, nodesdict, vd) # force mac addresses to be vpn-link only (like gateways for example) if params['vpn']: graph.mark_vpn(batadv_graph, frozenset(params['vpn'])) nodedb['nodes'] = list(nodesdict.values()) def extract_tunnel(nodes): macs = set() for node in nodes: try: for mac in node["nodeinfo"]["network"]["mesh"]["bat0"]["interfaces"]["tunnel"]: macs.add(mac) except KeyError: pass return macs graph.mark_vpn(batadv_graph, extract_tunnel(nodedb['nodes'])) batadv_graph = graph.merge_nodes(batadv_graph) batadv_graph = graph.to_undirected(batadv_graph) # write processed data to dest dir with open(nodes_fn, 'w') as f: json.dump(nodedb, f) graph_out = {'batadv': json_graph.node_link_data(batadv_graph), 'version': GRAPH_VERSION} with open(graph_fn, 'w') as f: json.dump(graph_out, f) with open(nodelist_fn, 'w') as f: json.dump(export_nodelist(now, nodedb), f) # optional rrd graphs (trigger with --rrd) if params['rrd']: rrd = RRD(params['rrd_path'], os.path.join(params['dest_dir'], 'nodes')) rrd.update_database(nodedb['nodes']) rrd.update_images()
def main(params): os.makedirs(params["dest_dir"], exist_ok=True) nodes_fn = os.path.join(params["dest_dir"], "nodes.json") graph_fn = os.path.join(params["dest_dir"], "graph.json") nodelist_fn = os.path.join(params["dest_dir"], "nodelist.json") now = datetime.utcnow().replace(microsecond=0) # parse mesh param and instantiate Alfred/Batman instances alfred_instances = [] batman_instances = [] for value in params["mesh"]: # (1) only batman-adv if, no alfred sock if ":" not in value: if len(params["mesh"]) > 1: raise ValueError("Multiple mesh interfaces require the use of " "alfred socket paths.") alfred_instances.append(Alfred(unix_sockpath=None)) batman_instances.append(Batman(mesh_interface=value)) else: # (2) batman-adv if + alfred socket try: batif, alfredsock = value.split(":") alfred_instances.append(Alfred(unix_sockpath=alfredsock)) batman_instances.append(Batman(mesh_interface=batif, alfred_sockpath=alfredsock)) except ValueError: raise ValueError('Unparseable value "{0}" in --mesh parameter.'.format(value)) # read nodedb state from node.json try: with open(nodes_fn, "r") as nodedb_handle: nodedb = json.load(nodedb_handle) except IOError: nodedb = {"nodes": dict()} # flush nodedb if it uses the old format if "links" in nodedb: nodedb = {"nodes": dict()} # set version we're going to output nodedb["version"] = NODES_VERSION # update timestamp and assume all nodes are offline nodedb["timestamp"] = now.isoformat() for node_id, node in nodedb["nodes"].items(): node["flags"]["online"] = False # integrate alfred nodeinfo for alfred in alfred_instances: nodeinfo = validate_nodeinfos(alfred.nodeinfo()) nodes.import_nodeinfo(nodedb["nodes"], nodeinfo, now, assume_online=True) # integrate static aliases data for aliases in params["aliases"]: with open(aliases, "r") as f: nodeinfo = validate_nodeinfos(json.load(f)) nodes.import_nodeinfo(nodedb["nodes"], nodeinfo, now, assume_online=False) nodes.reset_statistics(nodedb["nodes"]) for alfred in alfred_instances: nodes.import_statistics(nodedb["nodes"], alfred.statistics()) # acquire gwl and visdata for each batman instance mesh_info = [] for batman in batman_instances: vd = batman.vis_data() gwl = batman.gateway_list() mesh_info.append((vd, gwl)) # update nodedb from batman-adv data for vd, gwl in mesh_info: nodes.import_mesh_ifs_vis_data(nodedb["nodes"], vd) nodes.import_vis_clientcount(nodedb["nodes"], vd) nodes.mark_vis_data_online(nodedb["nodes"], vd, now) nodes.mark_gateways(nodedb["nodes"], gwl) # clear the nodedb from nodes that have not been online in $prune days if params["prune"]: nodes.prune_nodes(nodedb["nodes"], now, params["prune"]) # clear the nodedb from a specific node by MAC address if params["prunemac"]: nodes.prune_mac_node(nodedb["nodes"], params["prunemac"]) # build nxnetworks graph from nodedb and visdata batadv_graph = nx.DiGraph() for vd, gwl in mesh_info: graph.import_vis_data(batadv_graph, nodedb["nodes"], vd) # force mac addresses to be vpn-link only (like gateways for example) if params["vpn"]: graph.mark_vpn(batadv_graph, frozenset(params["vpn"])) def extract_tunnel(nodes): macs = set() for id, node in nodes.items(): try: for mac in node["nodeinfo"]["network"]["mesh"]["bat0"]["interfaces"]["tunnel"]: macs.add(mac) except KeyError: pass return macs graph.mark_vpn(batadv_graph, extract_tunnel(nodedb["nodes"])) batadv_graph = graph.merge_nodes(batadv_graph) batadv_graph = graph.to_undirected(batadv_graph) # write processed data to dest dir with open(nodes_fn, "w") as f: json.dump(nodedb, f) graph_out = {"batadv": json_graph.node_link_data(batadv_graph), "version": GRAPH_VERSION} with open(graph_fn, "w") as f: json.dump(graph_out, f) with open(nodelist_fn, "w") as f: json.dump(export_nodelist(now, nodedb), f) # optional rrd graphs (trigger with --rrd) if params["rrd"]: script_directory = os.path.dirname(os.path.realpath(__file__)) rrd = RRD(os.path.join(script_directory, "nodedb"), os.path.join(params["dest_dir"], "nodes")) rrd.update_database(nodedb["nodes"]) rrd.update_images()
def main(params): os.makedirs(params['dest_dir'], exist_ok=True) nodes_fn = os.path.join(params['dest_dir'], 'nodes.json') graph_fn = os.path.join(params['dest_dir'], 'graph.json') nodelist_fn = os.path.join(params['dest_dir'], 'nodelist.json') now = datetime.utcnow().replace(microsecond=0) # parse mesh param and instantiate Alfred/Batman instances alfred_instances = [] batman_instances = [] for value in params['mesh']: # (1) only batman-adv if, no alfred sock if ':' not in value: if len(params['mesh']) > 1: raise ValueError( 'Multiple mesh interfaces require the use of ' 'alfred socket paths.') alfred_instances.append(Alfred(unix_sockpath=None)) batman_instances.append(Batman(mesh_interface=value)) else: # (2) batman-adv if + alfred socket try: batif, alfredsock = value.split(':') alfred_instances.append(Alfred(unix_sockpath=alfredsock)) batman_instances.append(Batman(mesh_interface=batif, alfred_sockpath=alfredsock)) except ValueError: raise ValueError( 'Unparseable value "{0}" in --mesh parameter.'. format(value)) # read nodedb state from node.json try: with open(nodes_fn, 'r') as nodedb_handle: nodedb = json.load(nodedb_handle) except (IOError, ValueError): nodedb = {'nodes': dict()} # flush nodedb if it uses the old format if 'links' in nodedb: nodedb = {'nodes': dict()} # set version we're going to output nodedb['version'] = NODES_VERSION # update timestamp and assume all nodes are offline nodedb['timestamp'] = now.isoformat() for node_id, node in nodedb['nodes'].items(): node['flags']['online'] = False # integrate alfred nodeinfo for alfred in alfred_instances: nodeinfo = validate_nodeinfos(alfred.nodeinfo()) nodes.import_nodeinfo(nodedb['nodes'], nodeinfo, now, assume_online=True) # integrate static aliases data for aliases in params['aliases']: with open(aliases, 'r') as f: nodeinfo = validate_nodeinfos(json.load(f)) nodes.import_nodeinfo(nodedb['nodes'], nodeinfo, now, assume_online=False) nodes.reset_statistics(nodedb['nodes']) for alfred in alfred_instances: nodes.import_statistics(nodedb['nodes'], alfred.statistics()) # acquire gwl and visdata for each batman instance mesh_info = [] for batman in batman_instances: vd = batman.vis_data() gwl = batman.gateway_list() mesh_info.append((vd, gwl)) # integrate static online aliases data gwc = {} # parse aliases for gateways for aliases in params['aliases_online']: with open(aliases, 'r') as f: nodeinfo = validate_nodeinfos(json.load(f)) for node in nodeinfo: try: system = nodedb['nodes'][node.get('node_id')]['nodeinfo'].get('system', None) if system: # if role is gatway add mac to gateway list (gwl) if nodedb['nodes'][node.get('node_id')]['nodeinfo']['system'].get('role') == 'gateway': mac = nodedb['nodes'][node.get('node_id')]['nodeinfo']['network'].get('mac', None) if mac: # extend gwl gwl.append(mac) # fake visdata vd.append({"primary": mac}) gwc[mac] = 0 except KeyError: pass # parse data from aliases for aliases in params['aliases_online']: with open(aliases, 'r') as f: nodeinfo = validate_nodeinfos(json.load(f)) nodes.import_nodeinfo(nodedb['nodes'], nodeinfo, now, assume_online=True) for node in nodeinfo: gateways = nodedb['nodes'][node.get('node_id')]['nodeinfo']['network'].get('gateway', None) # if gateway in gwl fake visdata if gateways: if isinstance(gateways, str): gateways = [ gateways ] for gateway in gateways: gateway = ':'.join(gateway[i:i+2] for i in range(0,12,2)) if gateway in gwl: mac = nodedb['nodes'][node.get('node_id')]['nodeinfo']['network'].get('mac', None) if mac: # fake visdata vd.append({"primary": mac}) vd.append({"router": mac, "label": "TT", "gateway": gateway}) vd.append({"router": mac, "label": "1.000", "neighbor": gateway}) # count node to gateway clients try: gwc[gateway] += 1 except KeyError: pass # add Statistics from aliases try: statistics = node.get('statistics', None) except KeyError: pass if statistics: if nodedb['nodes'][node.get('node_id')].get('statistics'): nodedb['nodes'][node.get('node_id')]['statistics'].update(statistics) nodedb['nodes'][node.get('node_id')]['nodeinfo'].pop('statistics') if params['aliases_online']: # update gateway clients for gw in gwc: node = gw.replace(':', '') try: clients = nodedb['nodes'][node]['statistics'].get('clients') nodedb['nodes'][node]['statistics']['clients'] = clients + gwc[gw] clients = nodedb['nodes'][node]['statistics'].get('clients') except KeyError: pass # rebuild mesh_info mesh_info = [] mesh_info.append((vd, gwl)) # update nodedb from batman-adv data for vd, gwl in mesh_info: nodes.import_mesh_ifs_vis_data(nodedb['nodes'], vd) nodes.import_vis_clientcount(nodedb['nodes'], vd) nodes.mark_vis_data_online(nodedb['nodes'], vd, now) nodes.mark_gateways(nodedb['nodes'], gwl) # clear the nodedb from nodes that have not been online in $prune days if params['prune']: nodes.prune_nodes(nodedb['nodes'], now, params['prune']) # build nxnetworks graph from nodedb and visdata batadv_graph = nx.DiGraph() for vd, gwl in mesh_info: graph.import_vis_data(batadv_graph, nodedb['nodes'], vd) # force mac addresses to be vpn-link only (like gateways for example) if params['vpn']: graph.mark_vpn(batadv_graph, frozenset(params['vpn'])) def extract_tunnel(nodes): macs = set() for id, node in nodes.items(): try: for mac in node["nodeinfo"]["network"]["mesh"]["bat0"]["interfaces"]["tunnel"]: macs.add(mac) except KeyError: pass return macs graph.mark_vpn(batadv_graph, extract_tunnel(nodedb['nodes'])) batadv_graph = graph.merge_nodes(batadv_graph) batadv_graph = graph.to_undirected(batadv_graph) # optional anonymize data (trigger with --anonymize) if params['anonymize']: for node in nodedb['nodes']: if nodedb['nodes'][node]['nodeinfo'].get('owner'): nodedb['nodes'][node]['nodeinfo'].pop('owner') # write processed data to dest dir with open(nodes_fn, 'w') as f: json.dump(nodedb, f) graph_out = {'batadv': json_graph.node_link_data(batadv_graph), 'version': GRAPH_VERSION} with open(graph_fn, 'w') as f: json.dump(graph_out, f) with open(nodelist_fn, 'w') as f: json.dump(export_nodelist(now, nodedb), f) # optional rrd graphs (trigger with --rrd) if params['rrd']: script_directory = os.path.dirname(os.path.realpath(__file__)) rrd = RRD(os.path.join(script_directory, 'nodedb'), os.path.join(params['dest_dir'], 'nodes'), params['display_time_global'], params['display_time_node']) rrd.update_database(nodedb['nodes']) rrd.update_images()