mirror of
https://github.com/zvx-echo6/navi.git
synced 2026-08-26 17:31:37 +00:00
Per Matt's directive that navi-* should not call any /api/* on recon. navi-admin was the only navi service doing so (polling recon's /api/health and surfacing it in /api/admin/recon/info + the /api/admin/fleet fan-out). navi-admin is now the navi-only fleet view; recon has its own dashboard for recon-pipeline health. - admin_route.py: delete the /api/admin/recon/info handler; drop the recon config entry + RECON_HEALTH_URL/RECON_REPO_PATH env entries from /api/admin/navi-admin/info; refresh docstrings. - fleet.py: remove recon constants, recon_health_url/recon_repo_path/ recon_git_sha/wrap_recon_health, the now-unused shared.git_sha import, and the recon arms in build_fleet + dependency_summaries. /api/admin/fleet now reports only the 6 navi-* services. - tests: drop the 2 recon/info tests + recon scaffolding; strip recon assertions from fleet + self-info tests. 12 relevant tests pass (10 admin + 2 git_sha). shared/git_sha.py KEPT unchanged — it's a generic git_short_sha(path) helper used by every service's create_app(), not recon-specific. RECON_HEALTH_URL + RECON_REPO_PATH in /etc/navi-backend/navi-admin.env are now dead — flagged for out-of-band post-merge cleanup. Co-authored-by: Matt Johnson <mj@k7zvx.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
62 lines
2.2 KiB
Python
62 lines
2.2 KiB
Python
"""navi-admin routes — the fleet admin front door (extraction #7).
|
|
|
|
Two routes, all ``@require_auth`` (auth is also enforced at the Caddy edge in
|
|
prod; the Flask gate matches every other navi-* service and protects the
|
|
localhost :8427 path):
|
|
|
|
GET /api/admin/fleet fan-out aggregator across all navi-* services
|
|
GET /api/admin/navi-admin/info navi-admin's own admin-info (self-describe)
|
|
|
|
The per-service /api/admin/<svc>/info endpoints stay localhost-only (Phase A
|
|
§3/§7); this fleet endpoint is the single edge-exposed front door.
|
|
"""
|
|
import os
|
|
import time
|
|
|
|
from flask import Blueprint, jsonify, current_app, request
|
|
|
|
from shared.auth import require_auth
|
|
from shared.admin_info import build_info_response
|
|
|
|
from . import fleet
|
|
|
|
bp = Blueprint('navi_admin', __name__)
|
|
|
|
PORT = 8427
|
|
|
|
|
|
@bp.route('/api/admin/fleet')
|
|
@require_auth
|
|
def fleet_info():
|
|
"""Fan out to every navi-* service over localhost, merged. Forwards
|
|
the caller's X-Authentik-Username so the @require_auth upstreams accept it.
|
|
Never 5xx — per-service failures land in `errors`."""
|
|
return jsonify(fleet.build_fleet(request.user_id))
|
|
|
|
|
|
@bp.route('/api/admin/navi-admin/info')
|
|
@require_auth
|
|
def navi_admin_info():
|
|
"""navi-admin's own admin-info. No secrets (Phase A §9) — only non-secret
|
|
URLs/paths. `dependencies` reuses the same probes the fleet runs."""
|
|
metrics = current_app.config['METRICS']
|
|
info = build_info_response(
|
|
service='navi-admin',
|
|
version=current_app.config.get('VERSION', 'unknown'),
|
|
port=PORT,
|
|
# What it aggregates — non-secret, documents the fleet membership.
|
|
config={
|
|
'fanned_services': [{'name': n, 'port': p} for n, p in fleet.SERVICES],
|
|
},
|
|
env=[
|
|
{'name': 'NAVI_ADMIN_FANOUT_TIMEOUT_S', 'value': str(fleet.fanout_timeout())},
|
|
],
|
|
dependencies=fleet.dependency_summaries(request.user_id),
|
|
filesystem=[], # navi-admin owns no files / no DB (Phase A §9)
|
|
runtime={
|
|
'uptime_s': round(time.time() - metrics['start_time'], 1),
|
|
'request_count': metrics['request_count'],
|
|
'last_error_at': metrics['last_error_at'],
|
|
},
|
|
)
|
|
return jsonify(info)
|