Build interactive access topology map
This commit is contained in:
@@ -5,7 +5,7 @@ import os
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import psycopg
|
||||
from flask import Flask, abort, redirect, render_template, request, url_for
|
||||
from flask import Flask, abort, jsonify, redirect, render_template, request, url_for
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
@@ -245,8 +245,7 @@ def organization(organization_id):
|
||||
)
|
||||
|
||||
|
||||
@app.get("/network")
|
||||
def network():
|
||||
def load_network_flows():
|
||||
with db_connection() as connection, connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
"""
|
||||
@@ -286,13 +285,52 @@ def network():
|
||||
max_count = max([entry["count"] for entry in flow_rows] or [1])
|
||||
source_count = len({entry["source_ip"] for entry in flow_rows})
|
||||
target_count = len({entry["machine_name"] for entry in flow_rows})
|
||||
return flow_rows, max_count, source_count, target_count
|
||||
|
||||
|
||||
@app.get("/network")
|
||||
def network():
|
||||
flows, _, source_count, target_count = load_network_flows()
|
||||
return render_template(
|
||||
"network.html",
|
||||
flows=flow_rows,
|
||||
max_count=max_count,
|
||||
source_count=source_count,
|
||||
target_count=target_count,
|
||||
total_events=sum(entry["count"] for entry in flow_rows),
|
||||
total_events=sum(entry["count"] for entry in flows),
|
||||
path_count=len(flows),
|
||||
)
|
||||
|
||||
|
||||
@app.get("/api/network")
|
||||
def network_api():
|
||||
flows, max_count, source_count, target_count = load_network_flows()
|
||||
nodes = {}
|
||||
edges = []
|
||||
for index, flow in enumerate(flows):
|
||||
source_id = f"source:{flow['source_ip']}"
|
||||
target_id = f"target:{flow['machine_name']}"
|
||||
nodes[source_id] = {"data": {"id": source_id, "label": flow["source_ip"], "kind": "source"}}
|
||||
nodes[target_id] = {"data": {"id": target_id, "label": flow["machine_name"], "kind": "target"}}
|
||||
edges.append(
|
||||
{
|
||||
"data": {
|
||||
"id": f"flow:{index}",
|
||||
"source": source_id,
|
||||
"target": target_id,
|
||||
"count": flow["count"],
|
||||
"account": flow["account"],
|
||||
"event_type": flow["target"],
|
||||
"last_seen": str(flow["last_seen"] or "-"),
|
||||
"machine_name": flow["machine_name"],
|
||||
}
|
||||
}
|
||||
)
|
||||
return jsonify(
|
||||
{
|
||||
"elements": {"nodes": list(nodes.values()), "edges": edges},
|
||||
"max_count": max_count,
|
||||
"source_count": source_count,
|
||||
"target_count": target_count,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user