#!/usr/bin/env python3 """ AWS 统一账单数据导出工具 - 重构版本 功能: 1. 统一导出 AWS 生产和非生产账户的账单数据 2. 支持同时或单独导出不同环境的数据 3. 按日期和账户保存为 CSV 文件 4. 支持查询最近一周或指定日期区间的数据 用法示例: python -m aws.main_export --last-week # 导出所有环境从安全日期往前7天数据 python -m aws.main_export --env nonprod --days 30 # 只导出非生产环境最近30天 python -m aws.main_export --env prod --start-date 2025-04-01 --end-date 2025-09-30 python -m aws.main_export --start-date 2025-04-01 --end-date 2025-09-03 # 导出所有环境指定区间 """ import argparse import sys from datetime import datetime from aws.src.export.exporter import BillingExporter def parse_args(): """解析命令行参数""" parser = argparse.ArgumentParser( description='AWS 账单数据导出工具', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=__doc__ ) # 环境相关参数 parser.add_argument('--env', choices=['all', 'nonprod', 'prod', 'shared'], help='指定要导出的环境') parser.add_argument('--account-id', action='append', dest='account_ids', help='指定要导出的账户ID (可以指定多个)') # 日期范围参数 date_group = parser.add_mutually_exclusive_group() date_group.add_argument('--start-date', type=str, help='开始日期 (YYYY-MM-DD)') date_group.add_argument('--days', type=int, help='导出最近N天的数据') date_group.add_argument('--last-week', action='store_true', help='导出从安全日期往前7天的数据') parser.add_argument('--end-date', type=str, help='结束日期 (YYYY-MM-DD)') # 导出控制参数 parser.add_argument('--overwrite', action='store_true', help='覆盖已存在的文件') parser.add_argument('--refresh-cache', action='store_true', help='刷新账户缓存') parser.add_argument('--max-workers', type=int, default=5, help='最大并发工作线程数 (默认: 5)') # 配置文件 parser.add_argument('--config', type=str, help='配置文件路径') # 调试选项 parser.add_argument('--dry-run', action='store_true', help='试运行模式,只验证参数不执行导出') parser.add_argument('--verbose', '-v', action='store_true', help='详细输出') return parser.parse_args() def validate_args(args): """验证参数有效性""" errors = [] # 验证日期格式 if args.start_date: try: datetime.strptime(args.start_date, '%Y-%m-%d') except ValueError: errors.append("开始日期格式错误,应为 YYYY-MM-DD") if args.end_date: try: datetime.strptime(args.end_date, '%Y-%m-%d') except ValueError: errors.append("结束日期格式错误,应为 YYYY-MM-DD") # 验证日期逻辑 if args.start_date and args.end_date: start = datetime.strptime(args.start_date, '%Y-%m-%d') end = datetime.strptime(args.end_date, '%Y-%m-%d') if start > end: errors.append("开始日期不能晚于结束日期") # 验证线程数 if args.max_workers < 1 or args.max_workers > 20: errors.append("并发工作线程数应在 1-20 之间") return errors def main(): """主函数""" args = parse_args() # 验证参数 errors = validate_args(args) if errors: print("参数错误:") for error in errors: print(f" - {error}") sys.exit(1) if args.dry_run: print("试运行模式 - 只验证参数,不执行导出") try: # 初始化导出器 exporter = BillingExporter( config_path=args.config, max_workers=args.max_workers ) if args.dry_run: print("✓ 导出器初始化成功") print("✓ 配置文件加载成功") print("✓ 参数验证通过") return # 确定要导出的环境 environments = [] if args.env == 'all' or args.env is None: environments = exporter.env_manager.list_environments() else: environments = [args.env] # 解析日期参数 start_date = None end_date = None if args.start_date: start_date = datetime.strptime(args.start_date, '%Y-%m-%d') if args.end_date: end_date = datetime.strptime(args.end_date, '%Y-%m-%d') # 执行导出 stats = exporter.export( environments=environments, start_date=start_date, end_date=end_date, days=args.days, last_week=args.last_week, account_ids=args.account_ids, overwrite=args.overwrite, refresh_cache=args.refresh_cache ) # 检查是否有错误 if stats['errors']: print(f"\n⚠️ 导出过程中出现 {len(stats['errors'])} 个错误") sys.exit(1) else: print(f"\n✅ 导出完成!成功导出 {stats['exported_files']} 个文件") except KeyboardInterrupt: print("\n用户中断操作") sys.exit(130) except Exception as e: print(f"\n✗ 导出失败: {e}") if args.verbose: import traceback traceback.print_exc() sys.exit(1) if __name__ == "__main__": main()