diff --git a/main.py b/main.py index 77e5045..38f1b56 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,5 @@ -""" -main -""" +"""main""" import subprocess -import logging import argparse from pathlib import Path import yaml @@ -72,7 +69,7 @@ def parse_compose_config(file_path: Path) -> list[NginxConfig]: nginx_configs.append(conf) except Exception as e: - logger.error("解析服务 %s 配置失败: %s{str(e)}", name, str(e)) + logger.error("解析服务 %s 配置失败: %s", name, str(e)) continue return nginx_configs @@ -90,52 +87,86 @@ def parse_compose_config(file_path: Path) -> list[NginxConfig]: logger.error("未知错误: %s", str(e), exc_info=True) return False +def parse_yaml_config(file_path: Path) -> tuple[list[NginxConfig], list[NginxConfig]]: + """解析conf.yml配置文件""" + with open(file_path, 'r', encoding='utf-8') as f: + config = yaml.safe_load(f) + + inner_configs = [] + for compose_file in config['inner']['compose_file']: + inner_configs.extend(parse_compose_config(Path(compose_file))) + + outer_configs = [] + for domain, service_config in config['outter']['services'].items(): + outer_configs.append(NginxConfig( + name=domain, + host=service_config.get('host', config['outter']['host']), + port=service_config['port'], + web_socket_proxy=service_config.get('web_socket_proxy', False) + )) + + return inner_configs, outer_configs + def main(): """main""" - parser = argparse.ArgumentParser(description="Nginx自动化配置工具") - parser.add_argument('--compose-file', type=str, default=DOCKER_COMPOSE_FILE, - help="Docker Compose文件路径") - parser.add_argument('--debug', action='store_true', - help="启用调试模式") + parser = argparse.ArgumentParser(description="Nginx自动化配置工具", + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('-i', '--input', type=str, default='conf.yml', + help='配置文件路径 (默认: conf.yml)') + parser.add_argument('-t', '--type', choices=['all', 'inner', 'outter'], default='all', + help='配置类型选择:\n' + 'all - 同时处理内部和外部服务(默认)\n' + 'inner - 仅处理Docker compose服务\n' + 'outter - 仅处理外部服务') + parser.add_argument('--no-reload', action='store_true', + help='生成配置后禁用立即重载Nginx') + parser.add_argument('--rollback', action='store_true', + help='回滚到最近的有效配置') + parser.add_argument('--dry-run', action='store_true', + help='只生成配置不实际写入') + parser.add_argument('--verbose', action='store_true', + help='显示详细调试信息') args = parser.parse_args() - if args.debug: - logger.setLevel(logging.DEBUG) - logger.debug("调试模式已启用") + # 初始化配置器 + conf = NginxConfigurator() - # 前置检查 - if not validate_docker_network(): - logger.error("请先创建Docker网络: docker network create %s", NETWORK_NAME) + # 回滚操作 + if args.rollback: + if conf.rollback(): + logger.info("回滚成功") return # 配置生成 try: - logger.info("开始解析Docker Compose配置...") - compose_files:str = args.compose_file - configs = [] - for file in compose_files.split(','): - logger.info("parse %s", file) - config = parse_compose_config(file) - configs.extend(config) - logger.info("发现 %d 个需要代理的服务", len(configs)) + inner, outter = parse_yaml_config(Path(args.input)) - conf = NginxConfigurator() + # 根据类型选择配置 + if args.type == 'inner': + configs = inner + elif args.type == 'outter': + configs = outter + else: + configs = inner + outter + logger.info("共生成 %d 项配置(内部:%d 外部:%d)", + len(configs), len(inner), len(outter)) + + # 备份当前配置 conf.backup_config() - ret = conf.gen_and_save_config(configs) - if not ret: + # 预览模式 + if args.dry_run: + print(conf.gen_all_config(configs)) return - ret = conf.safe_reload() - if ret: - logger.info("全流程完成") - else: - logger.error("流程未完成,请检查错误日志") + # 写入配置 + if conf.gen_and_save_config(configs): + if not args.no_reload: + conf.safe_reload() except Exception as e: - logger.critical("主流程异常终止: %s", str(e), exc_info=args.debug) - + logger.critical("流程异常: %s", str(e), exc_info=args.verbose) if __name__ == "__main__": main() diff --git a/src/nginx.py b/src/nginx.py index 6d47092..b021414 100644 --- a/src/nginx.py +++ b/src/nginx.py @@ -178,20 +178,21 @@ server {{ self.logger.error("重载失败: %s", str(e)) return False - # def rollback(self) -> bool: - # """回滚到最近的有效配置""" - # backups = sorted(self.backup_dir.glob("*.bak.*"), - # key=os.path.getmtime, reverse=True) - # if not backups: - # self.logger.error("无可用的备份配置") - # return False - # try: - # shutil.copy(backups[0], self.output_dir / "generated.conf") - # self.logger.warning(f"已回滚到备份 {backups[0].name}") - # return self.safe_reload() - # except Exception as e: - # self.logger.error(f"回滚失败: {str(e)}") - # return False + def rollback(self) -> bool: + """回滚到最近的有效配置""" + raise NotImplementedError() + # backups = sorted(self.backup_dir.glob("*.bak.*"), + # key=os.path.getmtime, reverse=True) + # if not backups: + # self.logger.error("无可用的备份配置") + # return False + # try: + # shutil.copy(backups[0], self.output_dir / "generated.conf") + # self.logger.warning(f"已回滚到备份 {backups[0].name}") + # return self.safe_reload() + # except Exception as e: + # self.logger.error(f"回滚失败: {str(e)}") + # return False if __name__ == '__main__': config = NginxConfigurator()