from flask import Blueprint, jsonify, current_app from datetime import datetime from models import db from utils.logger import get_logger import smtplib import redis health_bp = Blueprint('health', __name__) logger = get_logger(__name__) @health_bp.route('/healthz', methods=['GET']) def health_check(): """Basic health check""" return jsonify({ 'status': 'healthy', 'timestamp': datetime.utcnow().isoformat() }), 200 @health_bp.route('/readiness', methods=['GET']) def readiness_check(): """Detailed readiness check""" try: checks = { 'database': False, 'ldap': False, 'smtp': False, 'redis': False } errors = [] # Check database try: db.session.execute(db.text('SELECT 1')) checks['database'] = True except Exception as e: errors.append(f"Database check failed: {str(e)}") logger.error(f"Database health check failed: {str(e)}") # Check LDAP try: if current_app.config.get('USE_MOCK_LDAP', False): from utils.mock_ldap import test_ldap_connection else: from utils.ldap_utils import test_ldap_connection if test_ldap_connection(): checks['ldap'] = True else: errors.append("LDAP connection failed") except Exception as e: errors.append(f"LDAP check failed: {str(e)}") logger.error(f"LDAP health check failed: {str(e)}") # Check SMTP try: from flask import current_app config = current_app.config if config['SMTP_USE_SSL']: server = smtplib.SMTP_SSL(config['SMTP_SERVER'], config['SMTP_PORT'], timeout=5) else: server = smtplib.SMTP(config['SMTP_SERVER'], config['SMTP_PORT'], timeout=5) if config['SMTP_USE_TLS']: server.starttls() server.quit() checks['smtp'] = True except Exception as e: errors.append(f"SMTP check failed: {str(e)}") logger.error(f"SMTP health check failed: {str(e)}") # Check Redis try: from flask import current_app r = redis.from_url(current_app.config['REDIS_URL']) r.ping() checks['redis'] = True except Exception as e: errors.append(f"Redis check failed: {str(e)}") logger.error(f"Redis health check failed: {str(e)}") # Determine overall status all_healthy = all(checks.values()) critical_healthy = checks['database'] # Database is critical if all_healthy: status_code = 200 status = 'healthy' elif critical_healthy: status_code = 200 status = 'degraded' else: status_code = 503 status = 'unhealthy' return jsonify({ 'status': status, 'checks': checks, 'errors': errors, 'timestamp': datetime.utcnow().isoformat() }), status_code except Exception as e: logger.error(f"Readiness check error: {str(e)}") return jsonify({ 'status': 'error', 'error': str(e), 'timestamp': datetime.utcnow().isoformat() }), 503 @health_bp.route('/liveness', methods=['GET']) def liveness_check(): """Kubernetes liveness probe""" try: # Simple check to see if the app is running return jsonify({ 'status': 'alive', 'timestamp': datetime.utcnow().isoformat() }), 200 except Exception as e: logger.error(f"Liveness check failed: {str(e)}") return jsonify({ 'status': 'dead', 'error': str(e) }), 503