mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-10-27 23:28:03 +09:00
The first pass left routes that hand the body straight to a service (create_zone(data), MonitorService.create(data), ...). Those services read it as a dict, so a body of null, [] or a bare string still crashed them into a 500. Agent long-poll, external webhook receivers and the routes that already type-check their body are left alone.
163 lines
4.9 KiB
Python
163 lines
4.9 KiB
Python
from flask import Blueprint, request, jsonify
|
|
from flask_jwt_extended import jwt_required
|
|
from app.middleware.rbac import admin_required
|
|
from app.services.monitoring_service import MonitoringService
|
|
from app.api._request import json_object
|
|
|
|
monitoring_bp = Blueprint('monitoring', __name__)
|
|
|
|
|
|
@monitoring_bp.route('/status', methods=['GET'])
|
|
@jwt_required()
|
|
def get_status():
|
|
"""Get monitoring status and current metrics."""
|
|
status = MonitoringService.get_status()
|
|
return jsonify(status), 200
|
|
|
|
|
|
@monitoring_bp.route('/metrics', methods=['GET'])
|
|
@jwt_required()
|
|
def get_metrics():
|
|
"""Get current system metrics."""
|
|
metrics = MonitoringService.get_current_metrics()
|
|
return jsonify(metrics), 200
|
|
|
|
|
|
@monitoring_bp.route('/alerts/check', methods=['GET'])
|
|
@jwt_required()
|
|
def check_alerts():
|
|
"""Check current threshold violations."""
|
|
alerts = MonitoringService.check_thresholds()
|
|
return jsonify({'alerts': alerts}), 200
|
|
|
|
|
|
@monitoring_bp.route('/alerts/history', methods=['GET'])
|
|
@jwt_required()
|
|
def get_alert_history():
|
|
"""Get alert history."""
|
|
limit = request.args.get('limit', 100, type=int)
|
|
alerts = MonitoringService.get_alert_history(limit)
|
|
return jsonify({'alerts': alerts}), 200
|
|
|
|
|
|
@monitoring_bp.route('/alerts/history', methods=['DELETE'])
|
|
@admin_required
|
|
def clear_alert_history():
|
|
"""Clear alert history."""
|
|
result = MonitoringService.clear_alert_history()
|
|
return jsonify(result), 200 if result['success'] else 400
|
|
|
|
|
|
@monitoring_bp.route('/config', methods=['GET'])
|
|
@admin_required
|
|
def get_config():
|
|
"""Get monitoring configuration."""
|
|
config = MonitoringService.get_config()
|
|
# Don't expose sensitive data
|
|
if 'email' in config and 'smtp_password' in config['email']:
|
|
config['email']['smtp_password'] = '***' if config['email']['smtp_password'] else ''
|
|
return jsonify(config), 200
|
|
|
|
|
|
@monitoring_bp.route('/config', methods=['PUT'])
|
|
@admin_required
|
|
def update_config():
|
|
"""Update monitoring configuration."""
|
|
data = json_object()
|
|
if not data:
|
|
return jsonify({'error': 'No data provided'}), 400
|
|
|
|
current_config = MonitoringService.get_config()
|
|
|
|
# Update config with new values
|
|
if 'enabled' in data:
|
|
current_config['enabled'] = bool(data['enabled'])
|
|
|
|
if 'thresholds' in data:
|
|
current_config['thresholds'] = {**current_config.get('thresholds', {}), **data['thresholds']}
|
|
|
|
if 'check_interval' in data:
|
|
current_config['check_interval'] = data['check_interval']
|
|
|
|
if 'email' in data:
|
|
email_config = current_config.get('email', {})
|
|
new_email = data['email']
|
|
|
|
# Preserve password if not provided or masked
|
|
if new_email.get('smtp_password') in [None, '', '***']:
|
|
new_email['smtp_password'] = email_config.get('smtp_password', '')
|
|
|
|
current_config['email'] = {**email_config, **new_email}
|
|
|
|
if 'webhook' in data:
|
|
current_config['webhook'] = {**current_config.get('webhook', {}), **data['webhook']}
|
|
|
|
result = MonitoringService.save_config(current_config)
|
|
return jsonify(result), 200 if result['success'] else 400
|
|
|
|
|
|
@monitoring_bp.route('/thresholds', methods=['GET'])
|
|
@jwt_required()
|
|
def get_thresholds():
|
|
"""Get alert thresholds."""
|
|
thresholds = MonitoringService.get_thresholds()
|
|
return jsonify({'thresholds': thresholds}), 200
|
|
|
|
|
|
@monitoring_bp.route('/thresholds', methods=['PUT'])
|
|
@admin_required
|
|
def update_thresholds():
|
|
"""Update alert thresholds."""
|
|
data = json_object()
|
|
if not data:
|
|
return jsonify({'error': 'No data provided'}), 400
|
|
|
|
result = MonitoringService.set_thresholds(data)
|
|
return jsonify(result), 200 if result['success'] else 400
|
|
|
|
|
|
@monitoring_bp.route('/start', methods=['POST'])
|
|
@admin_required
|
|
def start_monitoring():
|
|
"""Start background monitoring."""
|
|
result = MonitoringService.start_monitoring()
|
|
return jsonify(result), 200 if result['success'] else 400
|
|
|
|
|
|
@monitoring_bp.route('/stop', methods=['POST'])
|
|
@admin_required
|
|
def stop_monitoring():
|
|
"""Stop background monitoring."""
|
|
result = MonitoringService.stop_monitoring()
|
|
return jsonify(result), 200 if result['success'] else 400
|
|
|
|
|
|
@monitoring_bp.route('/test/email', methods=['POST'])
|
|
@admin_required
|
|
def test_email_alert():
|
|
"""Send a test email alert."""
|
|
test_alerts = [{
|
|
'type': 'test',
|
|
'severity': 'info',
|
|
'message': 'This is a test alert from ServerKit',
|
|
'value': 0,
|
|
'threshold': 0
|
|
}]
|
|
result = MonitoringService.send_email_alert(test_alerts)
|
|
return jsonify(result), 200 if result['success'] else 400
|
|
|
|
|
|
@monitoring_bp.route('/test/webhook', methods=['POST'])
|
|
@admin_required
|
|
def test_webhook_alert():
|
|
"""Send a test webhook alert."""
|
|
test_alerts = [{
|
|
'type': 'test',
|
|
'severity': 'info',
|
|
'message': 'This is a test alert from ServerKit',
|
|
'value': 0,
|
|
'threshold': 0
|
|
}]
|
|
result = MonitoringService.send_webhook_alert(test_alerts)
|
|
return jsonify(result), 200 if result['success'] else 400
|