添加服务器时使用dnspod自动创建dns记录

This commit is contained in:
jingrow 2025-04-20 00:58:32 +08:00
parent 2196c19ac7
commit f422b2c1af

View File

@ -221,6 +221,159 @@ class BaseServer(Document, TagHelpers):
self.update_virtual_machine_name()
def create_dns_record(self):
try:
domain = jingrow.get_pg("Root Domain", self.domain)
if domain.dns_provider == "DNSPod":
self.create_dns_record_dnspod(domain)
else:
self.create_dns_record_route53()
except Exception as e:
log_error("DNS记录创建异常", domain=self.domain, server=self.name, error=str(e))
def create_dns_record_dnspod(self, domain):
"""
使用腾讯云API创建或更新DNS记录
"""
try:
# 获取凭证
secret_id = domain.dnspod_app_id or ""
secret_key = domain.get_password("dnspod_app_token") or ""
if not secret_id or not secret_key:
log_error("未配置DNSPod凭证", domain=domain.name)
return
# 分离子域名
if self.name.endswith("." + domain.name):
sub_domain = self.name[:-len(domain.name)-1]
else:
log_error("域名配置错误", domain=domain.name, server=self.name)
return
# 使用腾讯云SDK
try:
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.dnspod.v20210323 import dnspod_client, models
except ImportError:
log_error("腾讯云SDK未安装请运行: pip install --user tencentcloud-sdk-python")
return
# 初始化认证
cred = credential.Credential(secret_id, secret_key)
httpProfile = HttpProfile()
httpProfile.endpoint = "dnspod.tencentcloudapi.com"
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = dnspod_client.DnspodClient(cred, "", clientProfile)
# 查询记录是否存在
record_id = None
try:
req = models.DescribeRecordListRequest()
params = {
"Domain": domain.name,
"Subdomain": sub_domain,
"RecordType": "A"
}
req.from_json_string(json.dumps(params))
resp = client.DescribeRecordList(req)
resp_dict = json.loads(resp.to_json_string())
records = resp_dict.get("RecordList", [])
for record in records:
if record.get("Name") == sub_domain and record.get("Type") == "A":
record_id = record.get("RecordId")
break
except TencentCloudSDKException as err:
# 如果是"记录列表为空"错误,这是正常的,表示记录不存在
if err.code == "ResourceNotFound.NoDataOfRecord":
record_id = None
else:
# 其他错误需要记录并抛出
log_error("腾讯云SDK查询记录错误", code=err.code, message=err.message)
return
# 腾讯云DNSPod的TTL值
# 免费版最低TTL可能是600秒
ttl_value = 3600 if self.pagetype == "Proxy Server" else 600
# 根据是否存在记录决定创建或修改
try:
if record_id:
# 修改记录
req = models.ModifyRecordRequest()
params = {
"Domain": domain.name,
"RecordId": record_id,
"RecordType": "A",
"RecordLine": "默认",
"Value": self.ip,
"TTL": ttl_value
}
req.from_json_string(json.dumps(params))
response = client.ModifyRecord(req)
else:
# 创建记录
req = models.CreateRecordRequest()
params = {
"Domain": domain.name,
"SubDomain": sub_domain,
"RecordType": "A",
"RecordLine": "默认",
"Value": self.ip,
"TTL": ttl_value
}
req.from_json_string(json.dumps(params))
response = client.CreateRecord(req)
except TencentCloudSDKException as err:
# 如果是TTL限制错误尝试更高的值
if err.code == "LimitExceeded.RecordTtlLimit":
log_error("TTL值超限尝试更高的TTL值", current_ttl=ttl_value)
# 尝试更高的TTL值 (1800秒 = 30分钟)
ttl_value = 1800
try:
if record_id:
# 修改记录
req = models.ModifyRecordRequest()
params = {
"Domain": domain.name,
"RecordId": record_id,
"RecordType": "A",
"RecordLine": "默认",
"Value": self.ip,
"TTL": ttl_value
}
req.from_json_string(json.dumps(params))
response = client.ModifyRecord(req)
else:
# 创建记录
req = models.CreateRecordRequest()
params = {
"Domain": domain.name,
"SubDomain": sub_domain,
"RecordType": "A",
"RecordLine": "默认",
"Value": self.ip,
"TTL": ttl_value
}
req.from_json_string(json.dumps(params))
response = client.CreateRecord(req)
except TencentCloudSDKException as inner_err:
log_error("即使提高TTL后仍然失败", code=inner_err.code, message=inner_err.message, ttl=ttl_value)
else:
log_error("DNS操作失败", code=err.code, message=err.message, action="创建或修改记录")
except Exception as e:
log_error("DNS记录创建异常", domain=domain.name, server=self.name, error=str(e))
def create_dns_record_route53(self):
try:
domain = jingrow.get_pg("Root Domain", self.domain)
client = boto3.client(