[dns] 希望能支持name.com
DNS 服务商信息
- 官网 (Website): name.com
- 中文名称 (Chinese Name): name
- 英文名称 (English Name): name
- 标准DNS服务商 (Standard DNS Provider): Yes
DNS 服务商文档链接
请提供以下相关文档的链接(如有):
- [ ] API 认证与签名 (Authorization & Signature):
- [ ] 查询/列出域名 (Query/List Domains):
- [ ] 查询/列出解析记录 (Query/List DNS Records):
- [ ] 创建解析记录 (Create DNS Record):
- [ ] 修改解析记录 (Update DNS Record):
- [ ] 其它配置或使用文档 (Other Configuration/Usage Docs, 可选):
- [ ] 官方或第三方Python SDK (Official or Third-party Python SDK, 可选):
其他补充信息(可选)
请补充任何有助于集成该 DNS 服务商的信息,例如常见问题、注意事项、特殊限制等。
感谢反馈,已确认这是一个“新增DNS服务商”需求。我们可以为 Name.com 实现一个标准的 BaseProvider 适配器,支持查询/创建/更新 A 和 AAAA 等记录。
下面是可行性评估、实现方案和需要您补充的资料。
结论
- 可实现:基于现有架构(BaseProvider + 内置 HTTP 工具),Name.com 的 REST API(推测为 v4)通常使用 Basic Auth,记录接口完整(列出/创建/更新)。实现难度中等。
- 预计 Provider 名称:建议使用
namecom,并兼容别名name、name_com。
我们需要您提供的官方文档链接(Issue 模板的勾选项)
为确保实现细节准确,请补全以下官方文档链接:
- API 认证与签名(Authorization & Signature)
- 查询/列出域名(List Domains)
- 查询/列出解析记录(List DNS Records)
- 创建解析记录(Create DNS Record)
- 修改解析记录(Update DNS Record)
- 其它配置或使用文档(可选)
- 官方或第三方 Python SDK(可选)
并附上 1~2 个实际响应样例(JSON),尤其是:
- 列出记录返回对象的字段名(例如
host或name,answer或value、是否有id) - 创建和更新请求体的字段(是否用
host/name+type+answer+ttl) - 认证方式(是否为 Basic Auth:用户名 + API Token;或专用 Header)
说明:我们已有 Namesilo/No-IP/Cloudflare 等实现示例。Name.com 若为 Basic Auth,可复用 No-IP 的“在 endpoint 中嵌入认证信息”的做法,或者使用 Header 形式。请以官方文档为准。
实现方案(拟定)
参考现有 Provider 结构:
- Base 类:
ddns/provider/_base.py - HTTP 工具:
ddns/util/http.py(支持 Basic Auth,当 URL 中包含https://user:pass@host时自动注入认证) - 参考:Cloudflare(JSON + Bearer)、Namesilo(GET + query token)、No-IP(Basic Auth)
新增文件:ddns/provider/namecom.py
拟采用 BaseProvider,支持完整 CRUD:
# coding=utf-8
from ._base import BaseProvider, TYPE_JSON, quote, join_domain
class NameComProvider(BaseProvider):
endpoint = "https://api.name.com"
content_type = TYPE_JSON
def _validate(self):
# Name.com 通常需要用户名 + API token(Basic Auth)
if not self.id:
raise ValueError("Name.com requires 'id' (username)")
if not self.token:
raise ValueError("Name.com requires 'token' (API token)")
# 将认证信息嵌入 endpoint,复用内置 BasicAuth 机制
protocol, domain = self.endpoint.split("://", 1)
self.endpoint = "{0}://{1}:{2}@{3}".format(
protocol, quote(self.id, safe=""), quote(self.token, safe=""), domain
)
def _request(self, method, path, **params):
# 过滤 None
params = {k: v for k, v in params.items() if v is not None}
# Name.com API 通常是 JSON body + JSON response
return self._http(method, path, body=params)
def _query_zone_id(self, domain):
# 方案A:查询单域名信息(若文档提供 /v4/domains/{domain})
# 方案B:列出域名并匹配(若仅提供 /v4/domains 列表)
# 若返回200且域名存在,则以主域名作为 zone_id
try:
res = self._http("GET", "/v4/domains/{}".format(domain))
if isinstance(res, dict):
return domain
except Exception:
pass
return None
def _query_record(self, zone_id, subdomain, main_domain, record_type, line, extra):
# 列出记录并匹配
data = self._http("GET", "/v4/domains/{}/records".format(main_domain))
if isinstance(data, dict):
records = data.get("records") or data.get("resource_record") or data.get("data") or []
name = join_domain(subdomain, main_domain)
# Name.com 可能使用 host/name + answer/value 字段,兼容性匹配
for r in records:
host = r.get("host") or r.get("name") or r.get("hostname")
if host in (subdomain, name) and r.get("type") == record_type:
return r
return None
def _create_record(self, zone_id, subdomain, main_domain, value, record_type, ttl, line, extra):
payload = {
# 字段名以官方文档为准,这里兼容常见命名
"host": subdomain if subdomain != "@" else "@",
"type": record_type,
"answer": value,
"ttl": ttl
}
res = self._http("POST", "/v4/domains/{}/records".format(main_domain), body=payload)
return bool(res)
def _update_record(self, zone_id, old_record, value, record_type, ttl, line, extra):
record_id = old_record.get("id") or old_record.get("record_id")
if not record_id:
self.logger.error("record id not found: %s", old_record)
return False
payload = {
"host": old_record.get("host") or old_record.get("name"),
"type": record_type,
"answer": value,
"ttl": ttl or old_record.get("ttl")
}
res = self._http("PUT", "/v4/domains/{}/records/{}".format(zone_id, record_id), body=payload)
return bool(res)
以上代码是骨架示例,最终字段名需以官方文档为准(常见为
host/name和answer)。我们会根据您提供的文档和样例调整。
注册 Provider 映射
文件:ddns/provider/__init__.py
from .namecom import NameComProvider
# ...
mapping = {
# ...
"namecom": NameComProvider,
"name": NameComProvider, # 兼容
"name_com": NameComProvider, # 兼容
}
更新 JSON Schema(v4.1)枚举
文件:schema/v4.1.json 的 enum 处增加:
- 在顶层
dns的 enum 中加入:"namecom" - 在
providers[].provider的 enum 中加入:"namecom"
文档
新增:doc/providers/namecom.md、doc/providers/namecom.en.md(用法、字段、示例)。
测试
新增:tests/test_provider_namecom.py
- 初始化校验(需要 id+token)
- 列出记录并匹配
- 创建与更新(用 MagicMock 模拟
_http返回) - 错误处理(认证失败、无记录、参数错误)
配置示例
- 命令行:
ddns --dns namecom --id your_username --token your_api_token --ipv4 host.example.com
- 多 Provider JSON:
{
"$schema": "https://ddns.newfuture.cc/schema/v4.1.json",
"providers": [
{
"provider": "namecom",
"id": "your_username",
"token": "your_api_token",
"ipv4": ["ddns.example.com"],
"ttl": 300
}
]
}
说明:若 Name.com 不支持自动创建记录(以官方文档为准),则需在控制台预先创建记录;否则 BaseProvider 会自动创建。
约束与注意事项
- 项目为 Python stdlib-only(不依赖第三方库),HTTP 通过
urllib封装实现,已支持:代理、SSL、重试、BasicAuth。 - Basic Auth 两种方式:
- 在 URL 中嵌入(
https://user:[email protected]),我们的http.request会自动处理。 - 或直接设置
Authorization: Basic ...头。但当前_http没有auth参数,采用 URL 方式更简单。
- 在 URL 中嵌入(
- 主域名作为 zone_id:若 Name.com API 没有“zone id”,可像 Namesilo 一样使用主域名字符串作为 ID。
- 字段名差异:请以官方文档为准,我们会适配
host/name、answer/value、以及id/record_id等别名。
下一步
- 请在此 Issue 补充上述官方文档链接与若干响应样例。
- 我们基于文档完善实现(字段与路径),提交 PR 与文档。
- 您可在本地通过
ddns --debug验证并反馈(日志会输出请求/响应,敏感信息已打码)。
参考文档:
- 开发指南(如何新增 Provider):doc/dev/provider.en.md
- 已有 Provider 列表与用法示例:doc/providers/README.en.md
感谢支持,我们随时跟进!
@Seifon 确认一下API对吗?或者补充一下链接