import os from typing import Dict from dotenv import load_dotenv from flask import Flask, jsonify, render_template, request from aws_service import ( AWSOperationError, ConfigError, AccountConfig, load_account_configs, replace_instance_ip, ) from db import init_db, load_disallowed_ips load_dotenv() app = Flask(__name__) def load_configs() -> Dict[str, AccountConfig]: config_path = os.getenv("AWS_CONFIG_PATH", "config/accounts.yaml") return load_account_configs(config_path) try: account_configs = load_configs() init_error = "" except ConfigError as exc: account_configs = {} init_error = str(exc) retry_limit = int(os.getenv("IP_RETRY_LIMIT", "5")) try: init_db() db_error = "" except Exception as exc: # noqa: BLE001 - surface DB connection issues to UI db_error = f"数据库初始化失败: {exc}" @app.route("/", methods=["GET"]) def index(): if init_error or db_error: return render_template("index.html", accounts=[], init_error=init_error or db_error) return render_template("index.html", accounts=account_configs.values(), init_error="") @app.route("/replace_ip", methods=["POST"]) def replace_ip(): if init_error or db_error: return jsonify({"error": init_error or db_error}), 500 ip_to_replace = request.form.get("ip_to_replace", "").strip() account_name = request.form.get("account_name", "").strip() if not ip_to_replace: return jsonify({"error": "请输入要替换的IP"}), 400 if account_name not in account_configs: return jsonify({"error": "无效的账户选择"}), 400 disallowed = load_disallowed_ips() account = account_configs[account_name] try: result = replace_instance_ip(ip_to_replace, account, disallowed, retry_limit) except AWSOperationError as exc: return jsonify({"error": str(exc)}), 400 return jsonify(result), 200 if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)