from flask import Flask, render_template, render_template_string import configparser import ssl from routes.main_routes import main_bp from routes.edit_routes import edit_bp from utils.stats_utils import fetch_haproxy_stats, parse_haproxy_stats from auth.auth_middleware import setup_auth from log_parser import parse_log_file import os import sys from utils.haproxy_config import update_haproxy_config, is_frontend_exist, count_frontends_and_backends BASE_DIR = os.path.abspath(os.path.dirname(__file__)) app = Flask( __name__, static_folder=os.path.join(BASE_DIR, 'static'), static_url_path='/static', template_folder=os.path.join(BASE_DIR, 'templates') ) CONFIG_DIR_DOCKER = '/etc/haproxy-configurator' CONFIG_DIR_LOCAL = './config' CONFIG_DIR_ENV = os.environ.get('CONFIG_DIR', None) if CONFIG_DIR_ENV and os.path.exists(CONFIG_DIR_ENV): CONFIG_DIR = CONFIG_DIR_ENV elif os.path.exists(CONFIG_DIR_DOCKER): CONFIG_DIR = CONFIG_DIR_DOCKER elif os.path.exists(CONFIG_DIR_LOCAL): CONFIG_DIR = CONFIG_DIR_LOCAL else: CONFIG_DIR = CONFIG_DIR_DOCKER AUTH_CFG = os.path.join(CONFIG_DIR, 'auth', 'auth.cfg') SSL_INI = os.path.join(CONFIG_DIR, 'ssl.ini') os.makedirs(os.path.dirname(AUTH_CFG), exist_ok=True) os.makedirs(os.path.dirname(SSL_INI), exist_ok=True) BASIC_AUTH_USERNAME = "admin" BASIC_AUTH_PASSWORD = "admin" try: auth_config = configparser.ConfigParser() auth_config.read(AUTH_CFG) if auth_config.has_section('auth'): BASIC_AUTH_USERNAME = auth_config.get('auth', 'username', fallback='admin') BASIC_AUTH_PASSWORD = auth_config.get('auth', 'password', fallback='admin') else: BASIC_AUTH_USERNAME = "admin" BASIC_AUTH_PASSWORD = "admin" except Exception as e: print(f"[APP] Auth config error: {e}, using defaults", flush=True) BASIC_AUTH_USERNAME = "admin" BASIC_AUTH_PASSWORD = "admin" app.register_blueprint(main_bp) app.register_blueprint(edit_bp) setup_auth(app) certificate_path = None private_key_path = None ssl_context = None try: config2 = configparser.ConfigParser() config2.read(SSL_INI) if config2.has_section('ssl'): certificate_path = config2.get('ssl', 'certificate_path') private_key_path = config2.get('ssl', 'private_key_path') else: print(f"[APP] ✗ No [ssl] section in {SSL_INI}", flush=True) sys.exit(1) if not os.path.exists(certificate_path): print(f"[APP] ✗ Certificate not found: {certificate_path}", flush=True) sys.exit(1) if not os.path.exists(private_key_path): print(f"[APP] ✗ Private key not found: {private_key_path}", flush=True) sys.exit(1) ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) ssl_context.load_cert_chain(certfile=certificate_path, keyfile=private_key_path) print(f"[APP] ✓ SSL context loaded", flush=True) except Exception as e: print(f"[APP] ✗ SSL error: {e}", flush=True) sys.exit(1) @app.route('/statistics') def display_haproxy_stats(): haproxy_stats = fetch_haproxy_stats() parsed_stats = parse_haproxy_stats(haproxy_stats) return render_template('statistics.html', stats=parsed_stats) @app.route('/logs') def display_logs(): log_file_path = '/var/log/haproxy.log' parsed_entries = parse_log_file(log_file_path) return render_template('logs.html', entries=parsed_entries) @app.route('/home') def home(): frontend_count, backend_count, acl_count, layer7_count, layer4_count = count_frontends_and_backends() return render_template('home.html', frontend_count=frontend_count, backend_count=backend_count, acl_count=acl_count, layer7_count=layer7_count, layer4_count=layer4_count) if __name__ == '__main__': app.run(host='::', port=5000, ssl_context=ssl_context, debug=True)