本文档面向开发者,详细说明如何扩展和修改 DDNS 配置系统。
DDNS 配置系统采用分层架构,支持多种配置源:
┌─────────────────────────────────────────────┐
│ 配置源(优先级) │
├─────────────────────────────────────────────┤
│ CLI 参数 > JSON 文件 > 环境变量 > 默认值 │
├─────────────────────────────────────────────┤
│ Config 类 │
│ 统一配置访问接口 │
├─────────────────────────────────────────────┤
│ Provider 和应用模块 │
└─────────────────────────────────────────────┘
核心模块:
ddns/config/cli.py
- 命令行参数解析ddns/config/json.py
- JSON 配置文件处理ddns/config/env.py
- 环境变量解析ddns/config/config.py
- Config 类实现Config 类是配置系统的核心,负责合并多个配置源:
class Config(object):
def __init__(self, cli_config=None, json_config=None, env_config=None):
self._cli_config = cli_config or {}
self._json_config = json_config or {}
self._env_config = env_config or {}
# 配置属性初始化
self.dns = self._get("dns", "debug")
self.endpoint = self._get("endpoint") # 新增的端点配置
def _get(self, key, default=None):
"""按优先级获取配置值:CLI > JSON > ENV > default"""
return (
self._cli_config.get(key) or
self._json_config.get(key) or
self._env_config.get(key) or
default
)
id
- DNS 服务商认证 IDtoken
- DNS 服务商 API Tokendns
- DNS 服务商标识 (默认: “debug”)endpoint
- 自定义 API 端点 (覆盖默认端点)ipv4
/ipv6
- 域名列表ttl
- DNS TTL 值proxy
- HTTP 代理设置log_level
- 日志级别SUPPORTED_PROVIDERS = [
"alidns", "callback", "cloudflare", "debug", "dnscom",
"dnspod_com", "dnspod", "he", "huaweidns", "noip", "tencentcloud"
]
添加新配置参数需要修改 4 个文件:
schema/v4.0.json
){
"properties": {
"my_param": {
"type": "string",
"title": "My Parameter",
"description": "Description of my parameter",
"default": "default_value"
}
}
}
ddns/config/cli.py
)def create_parser(description, doc, version, date):
# ...existing code...
parser.add_argument(
"--my-param",
help="Description of my parameter",
default=None
)
ddns/config/config.py
)class Config(object):
def __init__(self, cli_config=None, json_config=None, env_config=None):
# ...existing code...
self.my_param = self._get("my_param", "default_value")
def dict(self):
return {
# ...existing fields...
"my_param": self.my_param,
}
tests/test_config_config.py
)def test_my_param_configuration(self):
"""Test my_param configuration from different sources"""
# CLI 配置测试
config = Config(cli_config={"my_param": "cli_value"})
self.assertEqual(config.my_param, "cli_value")
# JSON 配置测试
config = Config(json_config={"my_param": "json_value"})
self.assertEqual(config.my_param, "json_value")
# 优先级测试
config = Config(
cli_config={"my_param": "cli_value"},
json_config={"my_param": "json_value"}
)
self.assertEqual(config.my_param, "cli_value") # CLI 优先
新参数自动支持环境变量,命名规则:DDNS_PARAM_NAME
export DDNS_MY_PARAM=value
需要在 SIMPLE_ARRAY_PARAMS
中注册:
# config.py
SIMPLE_ARRAY_PARAMS = ["ipv4", "ipv6", "proxy", "my_array_param"]
def split_array_string(value):
"""支持多种分隔符:逗号、分号"""
if isinstance(value, list):
return value
# 支持 "a,b" 或 "a;b" 格式
if "," in str(value):
return [item.strip() for item in value.split(",")]
elif ";" in str(value):
return [item.strip() for item in value.split(";")]
return [value]
使用 str_bool()
函数:
def str_bool(value):
"""将字符串转换为布尔值"""
if isinstance(value, bool):
return value
if str(value).lower() in ["true", "yes", "1", "on"]:
return True
if str(value).lower() in ["false", "no", "0", "off"]:
return False
return bool(value)
# 在 Config.__init__ 中
self.ttl = int(self._get("ttl")) if self._get("ttl") else None
self.cache = str_bool(self._get("cache", True))
self.proxy = self._get("proxy", []) # 自动处理数组
python -m ddns --dns=cloudflare --endpoint=https://api.custom.com/v4/
{
"dns": "cloudflare",
"endpoint": "https://api.custom.com/v4/",
"ipv4": ["example.com"]
}
export DDNS_DNS=cloudflare
export DDNS_ENDPOINT=https://api.custom.com/v4/
def validate_config(config):
"""验证配置完整性"""
errors = []
if not config.id or not config.token:
errors.append("id and token are required")
if config.dns not in SUPPORTED_DNS_PROVIDERS:
errors.append("Unsupported DNS provider: {}".format(config.dns))
if config.ttl and (config.ttl < 1 or config.ttl > 86400):
errors.append("TTL must be between 1 and 86400 seconds")
return errors
def debug_config(config):
"""输出配置信息(隐藏敏感数据)"""
config_dict = config.dict()
for key, value in config_dict.items():
if key == "token" and value:
value = value[:2] + "***" + value[-2:]
print("{}: {}".format(key, value))
# 运行配置相关测试
python -m unittest discover tests -k "test_config" -v
# 测试特定功能
python -m unittest tests.test_config_config.TestConfigPriority -v
def create_test_config(**overrides):
"""创建测试配置"""
default_config = {
"dns": "debug",
"id": "test_id",
"token": "test_token"
}
default_config.update(overrides)
return Config(json_config=default_config)
# 使用
config = create_test_config(dns="cloudflare", endpoint="https://api.test.com")
schema/v4.0.json
中定义cli.py
中添加 --param-name
config.py
中添加属性和 dict()
方法str_bool()
, int()
等转换函数endpoint
参数是 v4.0 新增功能,主要用于:
通过这个配置系统,开发者可以快速添加新功能参数,保持代码的一致性和可维护性。