callback container integrated fully
This commit is contained in:
+59
-28
@@ -7778,15 +7778,24 @@ def settings_software_page(request: Request):
|
||||
_require_admin(request)
|
||||
settings = _software_settings()
|
||||
callback_base = str(settings.get("callback_base_url", "") or "").strip().rstrip("/")
|
||||
callback_internal_base = str(os.getenv("CALLBACK_INTERNAL_BASE_URL", "http://callback:8001") or "http://callback:8001").strip().rstrip("/")
|
||||
return templates.TemplateResponse(
|
||||
"settings_software.html",
|
||||
{
|
||||
"request": request,
|
||||
"software_settings": settings,
|
||||
"callback_health_url": f"{callback_base}/api/software-callback/health" if callback_base else "",
|
||||
"callback_internal_health_url": f"{callback_internal_base}/api/software-callback/health",
|
||||
"callback_test_result": request.query_params.get("callback_test_result", ""),
|
||||
"callback_test_kind": request.query_params.get("callback_test_kind", ""),
|
||||
"callback_test_status": request.query_params.get("callback_test_status", ""),
|
||||
"callback_test_ms": request.query_params.get("callback_test_ms", ""),
|
||||
"callback_test_url": request.query_params.get("callback_test_url", ""),
|
||||
"callback_test_message": request.query_params.get("callback_test_message", ""),
|
||||
"debug_log": _software_debug_tail(),
|
||||
"debug_log_path": str(SOFTWARE_CALLBACK_DEBUG_LOG),
|
||||
"callback_dedicated_port": str(os.getenv("CALLBACK_PORT", "8090") or "8090"),
|
||||
"callback_bind_ip": str(os.getenv("CALLBACK_BIND_IP", "127.0.0.1") or "127.0.0.1"),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -7852,25 +7861,16 @@ def settings_software_save(
|
||||
)
|
||||
|
||||
|
||||
@app.post("/settings/software/test-callback")
|
||||
def settings_software_test_callback(request: Request):
|
||||
_require_admin(request)
|
||||
settings = _software_settings()
|
||||
callback_base = str(settings.get("callback_base_url", "") or "").strip().rstrip("/")
|
||||
if not callback_base:
|
||||
callback_base = str(request.base_url).rstrip("/")
|
||||
health_url = f"{callback_base}/api/software-callback/health"
|
||||
timeout = max(2, min(int(settings.get("callback_test_timeout_seconds", 10) or 10), 60))
|
||||
verify_tls = bool(settings.get("callback_test_verify_tls", True))
|
||||
def _run_callback_health_test(health_url: str, timeout: int, verify_tls: bool, test_kind: str) -> dict[str, str]:
|
||||
parsed = urllib.parse.urlsplit(health_url)
|
||||
|
||||
_software_debug_log("=" * 72, force=True)
|
||||
_software_debug_log("CALLBACK TEST started", force=True)
|
||||
_software_debug_log(f"Base URL: {callback_base}", force=True)
|
||||
_software_debug_log(f"CALLBACK HEALTH TEST started | kind={test_kind}", force=True)
|
||||
_software_debug_log(f"Health URL: {health_url}", force=True)
|
||||
_software_debug_log(f"Scheme: {parsed.scheme} | Host: {parsed.hostname} | Port: {parsed.port or ('443' if parsed.scheme == 'https' else '80')}", force=True)
|
||||
_software_debug_log(f"Timeout: {timeout}s | Verify TLS: {verify_tls}", force=True)
|
||||
|
||||
if parsed.scheme not in {"http", "https"} or not parsed.hostname:
|
||||
return {"ok": "0", "status": "-", "ms": "-", "url": health_url, "message": "Invalid health URL."}
|
||||
|
||||
try:
|
||||
dns_started = time.monotonic()
|
||||
addresses = sorted({item[4][0] for item in socket.getaddrinfo(parsed.hostname, parsed.port or (443 if parsed.scheme == "https" else 80), type=socket.SOCK_STREAM)})
|
||||
@@ -7886,37 +7886,68 @@ def settings_software_test_callback(request: Request):
|
||||
try:
|
||||
req = urllib.request.Request(
|
||||
health_url,
|
||||
headers={"User-Agent": f"AssetManager/{application_version()} CallbackTest"},
|
||||
headers={"User-Agent": f"AssetManager/{application_version()} CallbackHealthTest"},
|
||||
method="GET",
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=timeout, context=context) as response:
|
||||
body = response.read(65536).decode("utf-8", errors="replace")
|
||||
elapsed = (time.monotonic() - request_started) * 1000
|
||||
status = str(response.status)
|
||||
_software_debug_log(f"HTTP STATUS: {response.status} {response.reason} ({elapsed:.1f} ms)", force=True)
|
||||
_software_debug_log(f"Content-Type: {response.headers.get('Content-Type', '-')}", force=True)
|
||||
_software_debug_log(f"Response body: {body}", force=True)
|
||||
payload = json.loads(body)
|
||||
if response.status == 200 and payload.get("ok") is True:
|
||||
_software_debug_log("RESULT: Callback health endpoint is reachable.", force=True)
|
||||
return RedirectResponse(
|
||||
"/settings/software?toast_success=" + quote(_translate_request(request, "software.settings.test_success", "Callback endpoint is reachable.")),
|
||||
status_code=303,
|
||||
)
|
||||
raise ValueError("Health response did not contain ok=true")
|
||||
return {"ok": "1", "status": status, "ms": f"{elapsed:.1f}", "url": health_url, "message": "OK"}
|
||||
return {"ok": "0", "status": status, "ms": f"{elapsed:.1f}", "url": health_url, "message": "Health response did not contain ok=true."}
|
||||
except urllib.error.HTTPError as exc:
|
||||
elapsed = (time.monotonic() - request_started) * 1000
|
||||
body = exc.read(65536).decode("utf-8", errors="replace")
|
||||
_software_debug_log(f"HTTP ERROR: {exc.code} {exc.reason}", force=True)
|
||||
_software_debug_log(f"Response body: {body}", force=True)
|
||||
message = f"HTTP {exc.code}: {exc.reason}"
|
||||
return {"ok": "0", "status": str(exc.code), "ms": f"{elapsed:.1f}", "url": health_url, "message": f"HTTP {exc.code}: {exc.reason}"}
|
||||
except Exception as exc:
|
||||
elapsed = (time.monotonic() - request_started) * 1000
|
||||
_software_debug_log(f"REQUEST ERROR: {type(exc).__name__}: {exc}", force=True)
|
||||
message = f"{type(exc).__name__}: {exc}"
|
||||
return {"ok": "0", "status": "-", "ms": f"{elapsed:.1f}", "url": health_url, "message": f"{type(exc).__name__}: {exc}"}
|
||||
|
||||
_software_debug_log("RESULT: Callback health endpoint is not reachable.", force=True)
|
||||
return RedirectResponse(
|
||||
"/settings/software?toast_error=" + quote(_translate_request(request, "software.settings.test_failed", "Callback test failed: {error}", error=message)),
|
||||
status_code=303,
|
||||
)
|
||||
|
||||
def _callback_test_redirect(request: Request, result: dict[str, str], test_kind: str) -> RedirectResponse:
|
||||
params = urllib.parse.urlencode({
|
||||
"callback_test_result": result.get("ok", "0"),
|
||||
"callback_test_kind": test_kind,
|
||||
"callback_test_status": result.get("status", "-"),
|
||||
"callback_test_ms": result.get("ms", "-"),
|
||||
"callback_test_url": result.get("url", ""),
|
||||
"callback_test_message": result.get("message", ""),
|
||||
})
|
||||
return RedirectResponse(f"/settings/software?{params}", status_code=303)
|
||||
|
||||
|
||||
@app.post("/settings/software/test-callback")
|
||||
@app.post("/settings/software/test-callback-external")
|
||||
def settings_software_test_callback_external(request: Request):
|
||||
_require_admin(request)
|
||||
settings = _software_settings()
|
||||
callback_base = str(settings.get("callback_base_url", "") or "").strip().rstrip("/")
|
||||
if not callback_base:
|
||||
callback_base = str(request.base_url).rstrip("/")
|
||||
health_url = f"{callback_base}/api/software-callback/health"
|
||||
timeout = max(2, min(int(settings.get("callback_test_timeout_seconds", 10) or 10), 60))
|
||||
verify_tls = bool(settings.get("callback_test_verify_tls", True))
|
||||
result = _run_callback_health_test(health_url, timeout, verify_tls, "external")
|
||||
return _callback_test_redirect(request, result, "external")
|
||||
|
||||
|
||||
@app.post("/settings/software/test-callback-internal")
|
||||
def settings_software_test_callback_internal(request: Request):
|
||||
_require_admin(request)
|
||||
settings = _software_settings()
|
||||
internal_base = str(os.getenv("CALLBACK_INTERNAL_BASE_URL", "http://callback:8001") or "http://callback:8001").strip().rstrip("/")
|
||||
health_url = f"{internal_base}/api/software-callback/health"
|
||||
timeout = max(2, min(int(settings.get("callback_test_timeout_seconds", 10) or 10), 60))
|
||||
result = _run_callback_health_test(health_url, timeout, True, "internal")
|
||||
return _callback_test_redirect(request, result, "internal")
|
||||
|
||||
|
||||
@app.get("/settings/software/debug-log")
|
||||
|
||||
Reference in New Issue
Block a user