Files
ServerKit/backend/app/api/support_bundle.py
T
Juan DenisandClaude Fable 5 c3f356b6fb feat(cli): API-backed operator verbs and diagnostic support bundle
serverkit status / services / apps / doctor [--repair] / repair /
update / login-url / support-bundle. Break-glass auth mints a 10-minute
admin JWT in-process (audit-logged) — root on the box already implies
full control. The support bundle exports a secret-scrubbed zip of
versions, service states, setting shapes and recent job failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 15:21:22 -04:00

38 lines
1.2 KiB
Python

"""Support bundle API: build and download a scrubbed diagnostic zip.
Registration (app/__init__.py):
from app.api.support_bundle import support_bundle_bp
app.register_blueprint(support_bundle_bp, url_prefix='/api/v1/support-bundle')
"""
import os
from datetime import datetime
from flask import Blueprint, jsonify, send_file
from app.middleware.rbac import admin_required
from app.services import support_bundle_service
support_bundle_bp = Blueprint('support_bundle', __name__)
@support_bundle_bp.route('', methods=['POST'])
@admin_required
def build_support_bundle():
"""Build a diagnostic support bundle and return it as a zip download."""
try:
path = support_bundle_service.build()
except Exception as exc: # noqa: BLE001 - surface as a JSON error, not a 500 page
return jsonify({'error': f'Failed to build support bundle: {exc}'}), 500
if not os.path.isfile(path):
return jsonify({'error': 'Support bundle was not created'}), 500
filename = f"serverkit-support-{datetime.utcnow().strftime('%Y-%m-%d')}.zip"
return send_file(
path,
mimetype='application/zip',
as_attachment=True,
download_name=filename,
max_age=0,
)