- Support for single record deployment - Batch deployment from JSON config - Service quick deployment (Web/API/CDN) - .env file support for secure credentials - Complete documentation
172 lines
4.3 KiB
Python
Executable File
172 lines
4.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
DNSPod批量部署脚本
|
|
从配置文件批量创建DNS记录
|
|
"""
|
|
import os
|
|
import sys
|
|
import json
|
|
import time
|
|
from pathlib import Path
|
|
|
|
from deploy_record import (
|
|
deploy_record,
|
|
check_domain_exists,
|
|
create_domain,
|
|
load_env
|
|
)
|
|
|
|
# 加载 .env
|
|
load_env()
|
|
|
|
def load_config(config_file):
|
|
"""加载配置文件"""
|
|
if not Path(config_file).exists():
|
|
print(f"错误: 配置文件不存在: {config_file}")
|
|
return None
|
|
|
|
try:
|
|
with open(config_file, 'r', encoding='utf-8') as f:
|
|
return json.load(f)
|
|
except json.JSONDecodeError as e:
|
|
print(f"错误: 配置文件格式错误: {e}")
|
|
return None
|
|
|
|
def batch_deploy(domain, config, create_domain_flag=False, delay=0.5):
|
|
"""批量部署DNS记录"""
|
|
records = config.get('records', [])
|
|
|
|
if not records:
|
|
print("错误: 配置文件中没有记录")
|
|
return False
|
|
|
|
print(f"\n批量部署开始")
|
|
print(f"域名: {domain}")
|
|
print(f"记录数量: {len(records)}")
|
|
print(f"延迟: {delay}s\n")
|
|
|
|
# 检查域名是否存在
|
|
if not check_domain_exists(domain):
|
|
if create_domain_flag:
|
|
if not create_domain(domain):
|
|
return False
|
|
else:
|
|
print(f"✗ 域名不存在: {domain}")
|
|
print(f"提示: 使用 --create-domain 自动创建域名")
|
|
return False
|
|
|
|
# 统计
|
|
success_count = 0
|
|
fail_count = 0
|
|
skip_count = 0
|
|
|
|
# 部署每条记录
|
|
for idx, record_config in enumerate(records, 1):
|
|
print(f"\n[{idx}/{len(records)}] 正在部署...")
|
|
|
|
subdomain = record_config.get('subdomain', '@')
|
|
record_type = record_config.get('type')
|
|
value = record_config.get('value')
|
|
line = record_config.get('line', '默认')
|
|
ttl = record_config.get('ttl', 600)
|
|
remark = record_config.get('remark', '')
|
|
|
|
if not record_type or not value:
|
|
print(f"✗ 跳过: 缺少必要参数 (type或value)")
|
|
skip_count += 1
|
|
continue
|
|
|
|
# 部署记录
|
|
success = deploy_record(
|
|
domain=domain,
|
|
subdomain=subdomain,
|
|
record_type=record_type,
|
|
value=value,
|
|
line=line,
|
|
ttl=ttl,
|
|
force=True, # 批量模式自动更新
|
|
create_domain_flag=False,
|
|
remark=remark
|
|
)
|
|
|
|
if success:
|
|
success_count += 1
|
|
else:
|
|
fail_count += 1
|
|
|
|
# API限频延迟
|
|
if idx < len(records):
|
|
time.sleep(delay)
|
|
|
|
# 输出统计
|
|
print(f"\n{'='*50}")
|
|
print(f"批量部署完成")
|
|
print(f" 成功: {success_count}")
|
|
print(f" 失败: {fail_count}")
|
|
print(f" 跳过: {skip_count}")
|
|
print(f"{'='*50}\n")
|
|
|
|
return fail_count == 0
|
|
|
|
def main():
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description='DNSPod批量部署', formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog='''
|
|
配置文件格式 (JSON):
|
|
{
|
|
"records": [
|
|
{
|
|
"subdomain": "@",
|
|
"type": "A",
|
|
"value": "1.2.3.4",
|
|
"line": "默认",
|
|
"ttl": 600,
|
|
"remark": "主域名"
|
|
},
|
|
{
|
|
"subdomain": "www",
|
|
"type": "A",
|
|
"value": "1.2.3.4",
|
|
"line": "默认"
|
|
},
|
|
{
|
|
"subdomain": "api",
|
|
"type": "A",
|
|
"value": "1.2.3.5",
|
|
"line": "电信"
|
|
}
|
|
]
|
|
}
|
|
|
|
示例:
|
|
%(prog)s --domain example.com --config dns-config.json
|
|
%(prog)s --domain example.com --config dns-config.json --create-domain
|
|
%(prog)s --domain example.com --config dns-config.json --delay 1.0
|
|
''')
|
|
|
|
parser.add_argument('--domain', required=True, help='域名(如: example.com)')
|
|
parser.add_argument('--config', required=True, help='配置文件路径(JSON格式)')
|
|
parser.add_argument('--create-domain', action='store_true', help='域名不存在时自动创建')
|
|
parser.add_argument('--delay', type=float, default=0.5, help='API调用间隔(秒, 默认: 0.5, 避免限频)')
|
|
|
|
args = parser.parse_args()
|
|
|
|
# 加载配置
|
|
config = load_config(args.config)
|
|
if not config:
|
|
sys.exit(1)
|
|
|
|
# 批量部署
|
|
success = batch_deploy(
|
|
domain=args.domain,
|
|
config=config,
|
|
create_domain_flag=args.create_domain,
|
|
delay=args.delay
|
|
)
|
|
|
|
sys.exit(0 if success else 1)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|