diff --git a/jcloud/jcloud/pagetype/server/server.py b/jcloud/jcloud/pagetype/server/server.py index 2ec173f..7f72331 100644 --- a/jcloud/jcloud/pagetype/server/server.py +++ b/jcloud/jcloud/pagetype/server/server.py @@ -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(