mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2026-02-04 11:20:31 -07:00
More VPN Tunnel Changes
This commit is contained in:
@@ -129,6 +129,10 @@ def _make_service_logger(base: Path, logger: logging.Logger) -> Callable[[str, s
|
||||
try:
|
||||
base.mkdir(parents=True, exist_ok=True)
|
||||
path = base / f"{service}.log"
|
||||
try:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
except Exception:
|
||||
pass
|
||||
_rotate_daily(path)
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
resolved_scope = _infer_server_scope(msg, scope)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# API Endpoints (if applicable):
|
||||
# - POST /api/tunnel/connect (Token Authenticated) - Issues VPN session material for an agent.
|
||||
# - GET /api/tunnel/status (Token Authenticated) - Returns VPN status for an agent.
|
||||
# - GET /api/tunnel/active (Token Authenticated) - Lists active VPN tunnel sessions.
|
||||
# - DELETE /api/tunnel/disconnect (Token Authenticated) - Tears down VPN session for an agent.
|
||||
# ======================================================
|
||||
|
||||
@@ -120,6 +121,21 @@ def _infer_endpoint_host(req) -> str:
|
||||
def register_tunnel(app, adapters: "EngineServiceAdapters") -> None:
|
||||
blueprint = Blueprint("vpn_tunnel", __name__)
|
||||
logger = adapters.context.logger.getChild("vpn_tunnel.api")
|
||||
service_log = adapters.service_log
|
||||
|
||||
def _service_log_event(message: str, *, level: str = "INFO") -> None:
|
||||
if not callable(service_log):
|
||||
return
|
||||
try:
|
||||
service_log("VPN_Tunnel/tunnel", message, level=level)
|
||||
except Exception:
|
||||
logger.debug("vpn_tunnel service log write failed", exc_info=True)
|
||||
|
||||
def _request_remote() -> str:
|
||||
forwarded = (request.headers.get("X-Forwarded-For") or "").strip()
|
||||
if forwarded:
|
||||
return forwarded.split(",")[0].strip()
|
||||
return (request.remote_addr or "").strip()
|
||||
|
||||
@blueprint.route("/api/tunnel/connect", methods=["POST"])
|
||||
def connect_tunnel():
|
||||
@@ -139,15 +155,37 @@ def register_tunnel(app, adapters: "EngineServiceAdapters") -> None:
|
||||
try:
|
||||
tunnel_service = _get_tunnel_service(adapters)
|
||||
endpoint_host = _infer_endpoint_host(request)
|
||||
_service_log_event(
|
||||
"vpn_api_connect_request agent_id={0} operator={1} endpoint_host={2} remote={3}".format(
|
||||
agent_id,
|
||||
operator_id or "-",
|
||||
endpoint_host or "-",
|
||||
_request_remote() or "-",
|
||||
)
|
||||
)
|
||||
payload = tunnel_service.connect(
|
||||
agent_id=agent_id,
|
||||
operator_id=operator_id,
|
||||
endpoint_host=endpoint_host,
|
||||
)
|
||||
except Exception as exc:
|
||||
_service_log_event(
|
||||
"vpn_api_connect_failed agent_id={0} operator={1} error={2}".format(
|
||||
agent_id,
|
||||
operator_id or "-",
|
||||
str(exc),
|
||||
),
|
||||
level="ERROR",
|
||||
)
|
||||
logger.warning("vpn connect failed for agent_id=%s: %s", agent_id, exc)
|
||||
return jsonify({"error": "connect_failed", "detail": str(exc)}), 500
|
||||
|
||||
_service_log_event(
|
||||
"vpn_api_connect_response agent_id={0} tunnel_id={1} status=ok".format(
|
||||
payload.get("agent_id", agent_id),
|
||||
payload.get("tunnel_id", "-"),
|
||||
)
|
||||
)
|
||||
return jsonify(payload), 200
|
||||
|
||||
@blueprint.route("/api/tunnel/status", methods=["GET"])
|
||||
@@ -163,18 +201,51 @@ def register_tunnel(app, adapters: "EngineServiceAdapters") -> None:
|
||||
|
||||
tunnel_service = _get_tunnel_service(adapters)
|
||||
payload = tunnel_service.status(agent_id)
|
||||
bump = _normalize_text(request.args.get("bump") or "")
|
||||
_service_log_event(
|
||||
"vpn_api_status_request agent_id={0} bump={1} remote={2}".format(
|
||||
agent_id,
|
||||
"true" if bump else "false",
|
||||
_request_remote() or "-",
|
||||
)
|
||||
)
|
||||
if not payload:
|
||||
_service_log_event(
|
||||
"vpn_api_status_response agent_id={0} status=down".format(agent_id)
|
||||
)
|
||||
return jsonify({"status": "down", "agent_id": agent_id}), 200
|
||||
payload["status"] = "up"
|
||||
bump = _normalize_text(request.args.get("bump") or "")
|
||||
if bump:
|
||||
tunnel_service.bump_activity(agent_id)
|
||||
_service_log_event(
|
||||
"vpn_api_status_response agent_id={0} status=up tunnel_id={1}".format(
|
||||
agent_id,
|
||||
payload.get("tunnel_id", "-"),
|
||||
)
|
||||
)
|
||||
return jsonify(payload), 200
|
||||
|
||||
@blueprint.route("/api/tunnel/connect/status", methods=["GET"])
|
||||
def tunnel_connect_status():
|
||||
return tunnel_status()
|
||||
|
||||
@blueprint.route("/api/tunnel/active", methods=["GET"])
|
||||
def tunnel_active():
|
||||
requirement = _require_login(app)
|
||||
if requirement:
|
||||
payload, status = requirement
|
||||
return jsonify(payload), status
|
||||
|
||||
tunnel_service = _get_tunnel_service(adapters)
|
||||
sessions = list(tunnel_service.list_sessions())
|
||||
_service_log_event(
|
||||
"vpn_api_active_response count={0} remote={1}".format(
|
||||
len(sessions),
|
||||
_request_remote() or "-",
|
||||
)
|
||||
)
|
||||
return jsonify({"count": len(sessions), "tunnels": sessions}), 200
|
||||
|
||||
@blueprint.route("/api/tunnel/disconnect", methods=["DELETE"])
|
||||
def disconnect_tunnel():
|
||||
requirement = _require_login(app)
|
||||
@@ -188,6 +259,15 @@ def register_tunnel(app, adapters: "EngineServiceAdapters") -> None:
|
||||
reason = _normalize_text(body.get("reason") or "operator_stop")
|
||||
|
||||
tunnel_service = _get_tunnel_service(adapters)
|
||||
_service_log_event(
|
||||
"vpn_api_disconnect_request agent_id={0} tunnel_id={1} reason={2} operator={3} remote={4}".format(
|
||||
agent_id or "-",
|
||||
tunnel_id or "-",
|
||||
reason or "-",
|
||||
(_current_user(app) or {}).get("username") or "-",
|
||||
_request_remote() or "-",
|
||||
)
|
||||
)
|
||||
stopped = False
|
||||
if tunnel_id:
|
||||
stopped = tunnel_service.disconnect_by_tunnel(tunnel_id, reason=reason)
|
||||
@@ -197,8 +277,21 @@ def register_tunnel(app, adapters: "EngineServiceAdapters") -> None:
|
||||
return jsonify({"error": "agent_id_required"}), 400
|
||||
|
||||
if not stopped:
|
||||
_service_log_event(
|
||||
"vpn_api_disconnect_not_found agent_id={0} tunnel_id={1}".format(
|
||||
agent_id or "-",
|
||||
tunnel_id or "-",
|
||||
),
|
||||
level="WARNING",
|
||||
)
|
||||
return jsonify({"error": "not_found"}), 404
|
||||
|
||||
_service_log_event(
|
||||
"vpn_api_disconnect_response agent_id={0} tunnel_id={1} status=stopped".format(
|
||||
agent_id or "-",
|
||||
tunnel_id or "-",
|
||||
)
|
||||
)
|
||||
return jsonify({"status": "stopped", "reason": reason}), 200
|
||||
|
||||
app.register_blueprint(blueprint)
|
||||
|
||||
Reference in New Issue
Block a user