diff --git a/README.md b/README.md index fb89d9fa77b..9da238404c2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ### 修复腾讯云 DNS 无法调用 --update 2023.1.3 - [API 2.0下线通知](https://cloud.tencent.com/document/product/1278/82311) + [API 2.0下线通知](https://cloud.tencent.com/document/product/1278/82311) By github@z0z0r4 ### 新增支持Actions自选更新V4或V6 ——update 2022.12.19 > 使用方法 diff --git a/cf2dns.py b/cf2dns.py index 7e8e7a45289..cc1394942f3 100644 --- a/cf2dns.py +++ b/cf2dns.py @@ -3,186 +3,186 @@ # Mail: tongdongdong@outlook.com import random import time -import os import requests -from dns.qCloud import QcloudApiv3 # QcloudApiv3 DNSPod 的 API 更新了... +from dns.qCloud import QcloudApiv3 # QcloudApiv3 DNSPod 的 API 更新了 By github@z0z0r4 from dns.aliyun import AliApi from dns.huawei import HuaWeiApi -import logging +from log import Logger import traceback -import json - -log_cf2dns = logging.basicConfig(filename='cf2dns.log', - format='%(asctime)s - %(levelname)s - %(message)s', - level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S") - - -def log_error(msg: str): - logging.error(msg) - print( - f'[Error] [{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}] {msg}') - - -def log_info(msg: str): - logging.info(msg) - print( - f'[INFO] [{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}] {msg}') - - -default_conf = { - "cf_api_key": "o1zrmHAF", - "domains": {"hostxxnit.com": - {"@": ["CM", "CU", "CT"], - "shop": ["CM", "CU", "CT"], - "stock": ["CM", "CU", "CT"]}, - "xxxx.me": {"@": ["CM", "CU", "CT"], - "vv": ["CM", "CU", "CT"]} - }, - "affect_num": 2, - "dns_server": 1, - "region_hw": "", - "region_ali": "", - "ttl": 600, - "record_type": "A", - "secret_id": "", - "secret_key": "" -} - -# 添加配置文件 -if not os.path.exists("config.json"): - with open("config.json", "w") as f: - json.dump(default_conf, f) - log_error("已初始化配置文件,请修改 config.json") - exit() -else: - with open("config.json") as f: - conf = json.load(f) - log_info("成功加载 config.json") -# 可以从 https://shop.hostmonit.com 获取 -KEY = conf["cf_api_key"] +#可以从https://shop.hostmonit.com获取 +KEY = "o1zrmHAF" -# CM:移动 CU:联通 CT:电信 AB:境外 DEF:默认 -# 修改需要更改的 DNSPod域名和子域名 -DOMAINS = conf["domains"] +#CM:移动 CU:联通 CT:电信 AB:境外 DEF:默认 +#修改需要更改的dnspod域名和子域名 +DOMAINS = { + "hostxxnit.com": {"@": ["CM","CU","CT"], "shop": ["CM", "CU", "CT"], "stock": ["CM","CU","CT"]}, + "484848.xyz": {"@": ["CM","CU","CT"], "shop": ["CM","CU","CT"]} +} -# 解析生效条数 免费的DNSPod相同线路最多支持2条解析 -AFFECT_NUM = conf["affect_num"] +#解析生效条数 免费的DNSPod相同线路最多支持2条解析 +AFFECT_NUM = 2 -# DNS服务商 如果使用DNSPod改为1 如果使用阿里云解析改成2 如果使用华为云解析改成3 -DNS_SERVER = conf["dns_server"] +#DNS服务商 如果使用DNSPod改为1 如果使用阿里云解析改成2 如果使用华为云解析改成3 +DNS_SERVER = 1 -# 如果使用华为云解析 需要从API凭证-项目列表中获取 -REGION_HW = conf["region_hw"] +#如果使用华为云解析 需要从API凭证-项目列表中获取 +REGION_HW = 'cn-east-3' -# 如果使用阿里云解析 REGION出现错误再修改 默认不需要修改 https://help.aliyun.com/document_detail/198326.html -REGION_ALI = conf["region_ali"] +#如果使用阿里云解析 REGION出现错误再修改 默认不需要修改 https://help.aliyun.com/document_detail/198326.html +REGION_ALI = 'cn-hongkong' -# 解析生效时间,默认为600秒 如果不是DNS付费版用户 不要修改!!! -TTL = conf["ttl"] +#解析生效时间,默认为600秒 如果不是DNS付费版用户 不要修改!!! +TTL = 600 -# A为筛选出IPv4的IP AAAA为筛选出IPv6的IP -RECORD_TYPE = conf["record_type"] +#v4为筛选出IPv4的IP v6为筛选出IPv6的IP +TYPE = 'v4' -# API 密钥 -# 腾讯云后台获取 https://console.cloud.tencent.com/cam/capi -# 阿里云后台获取 https://help.aliyun.com/document_detail/53045.html?spm=a2c4g.11186623.2.11.2c6a2fbdh13O53 注意需要添加DNS控制权限 AliyunDNSFullAccess -# 华为云后台获取 https://support.huaweicloud.com/devg-apisign/api-sign-provide-aksk.html -SECRETID = conf["secret_id"] -SECRETKEY = conf["secret_key"] +#API 密钥 +#腾讯云后台获取 https://console.cloud.tencent.com/cam/capi +#阿里云后台获取 https://help.aliyun.com/document_detail/53045.html?spm=a2c4g.11186623.2.11.2c6a2fbdh13O53 注意需要添加DNS控制权限 AliyunDNSFullAccess +#华为云后台获取 https://support.huaweicloud.com/devg-apisign/api-sign-provide-aksk.html +SECRETID = 'WTTCWxxxxxxxxxxxxxxxxxxxxx84O0V' +SECRETKEY = 'GXkG6D4X1Nxxxxxxxxxxxxxxxxxxxxx4lRg6lT' +log_cf2dns = Logger('cf2dns.log', level='debug') def get_optimization_ip(): try: - response = requests.post('https://api.hostmonit.com/get_optimization_ip', json={ - "key": KEY, "type": "v4" if RECORD_TYPE == "A" else "v6"}, headers={'Content-Type': 'application/json'}) + headers = headers = {'Content-Type': 'application/json'} + data = {"key": KEY, "type": TYPE} + response = requests.post('https://api.hostmonit.com/get_optimization_ip', json=data, headers=headers) if response.status_code == 200: - resp_json = response.json() - if resp_json["code"] == 200: - return resp_json + return response.json() else: - log_error(f'获取 Cloudflare IP 失败 {response.status_code}') + log_cf2dns.logger.error("CHANGE OPTIMIZATION IP ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----MESSAGE: REQUEST STATUS CODE IS NOT 200") + return None except Exception as e: - traceback.print_exc() - log_error(f"获取 Cloudflare IP 失败 {str(e)}") - + log_cf2dns.logger.error("CHANGE OPTIMIZATION IP ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----MESSAGE: " + str(e)) + return None -def changeDNS(line, c_info, domain, sub_domain, cloud): - global AFFECT_NUM, RECORD_TYPE +def changeDNS(line, s_info, c_info, domain, sub_domain, cloud): + global AFFECT_NUM, TYPE + if TYPE == 'v6': + recordType = "AAAA" + else: + recordType = "A" lines = {"CM": "移动", "CU": "联通", "CT": "电信", "AB": "境外", "DEF": "默认"} line = lines[line] try: - create_num = AFFECT_NUM - for i in range(create_num): - if len(c_info) == 0: - break - cf_ip = c_info.pop(random.randint(0, len(c_info)-1))["ip"] - cloud.create_record( - domain, sub_domain, cf_ip, RECORD_TYPE, line, TTL) - log_info( - f'CREATE DNS SUCCESS - DOMAIN: {domain} SUBDOMAIN: {sub_domain} RECORDLINE: {line} VALUE: {cf_ip}') + create_num = AFFECT_NUM - len(s_info) + if create_num == 0: + for info in s_info: + if len(c_info) == 0: + break + cf_ip = c_info.pop(random.randint(0,len(c_info)-1))["ip"] + if cf_ip in str(s_info): + continue + ret = cloud.change_record(domain, info["recordId"], sub_domain, cf_ip, recordType, line, TTL) + if(DNS_SERVER != 1 or ret["code"] == 0): + log_cf2dns.logger.info("CHANGE DNS SUCCESS: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip ) + else: + log_cf2dns.logger.error("CHANGE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip + "----MESSAGE: " + ret["message"] ) + elif create_num > 0: + for i in range(create_num): + if len(c_info) == 0: + break + cf_ip = c_info.pop(random.randint(0,len(c_info)-1))["ip"] + if cf_ip in str(s_info): + continue + ret = cloud.create_record(domain, sub_domain, cf_ip, recordType, line, TTL) + if(DNS_SERVER != 1 or ret["code"] == 0): + log_cf2dns.logger.info("CREATE DNS SUCCESS: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----VALUE: " + cf_ip ) + else: + log_cf2dns.logger.error("CREATE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip + "----MESSAGE: " + ret["message"] ) + else: + for info in s_info: + if create_num == 0 or len(c_info) == 0: + break + cf_ip = c_info.pop(random.randint(0,len(c_info)-1))["ip"] + if cf_ip in str(s_info): + create_num += 1 + continue + ret = cloud.change_record(domain, info["recordId"], sub_domain, cf_ip, recordType, line, TTL) + if(DNS_SERVER != 1 or ret["code"] == 0): + log_cf2dns.logger.info("CHANGE DNS SUCCESS: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip ) + else: + log_cf2dns.logger.error("CHANGE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip + "----MESSAGE: " + ret["message"] ) + create_num += 1 except Exception as e: - traceback.print_exc() - log_error(f'CHANGE DNS ERROR - MESSAGE: {str(e)}') - + log_cf2dns.logger.error("CHANGE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----MESSAGE: " + str(e)) def main(cloud): - global AFFECT_NUM, RECORD_TYPE + global AFFECT_NUM, TYPE + if TYPE == 'v6': + recordType = "AAAA" + else: + recordType = "A" if len(DOMAINS) > 0: try: cfips = get_optimization_ip() - if cfips == None: - log_error(f'GET CLOUDFLARE IP ERROR') + if cfips == None or cfips["code"] != 200: + log_cf2dns.logger.error("GET CLOUDFLARE IP ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----MESSAGE: " + str(cfips["info"])) return cf_cmips = cfips["info"]["CM"] cf_cuips = cfips["info"]["CU"] cf_ctips = cfips["info"]["CT"] for domain, sub_domains in DOMAINS.items(): for sub_domain, lines in sub_domains.items(): - # 删除对应 recordType 的解析 - ret = cloud.get_record(domain, 20, sub_domain, RECORD_TYPE) - if ret["code"] == 0: + temp_cf_cmips = cf_cmips.copy() + temp_cf_cuips = cf_cuips.copy() + temp_cf_ctips = cf_ctips.copy() + temp_cf_abips = cf_ctips.copy() + temp_cf_defips = cf_ctips.copy() + if DNS_SERVER == 1: + ret = cloud.get_record(domain, 20, sub_domain, "CNAME") + if ret["code"] == 0: + for record in ret["data"]["records"]: + if record["line"] == "移动" or record["line"] == "联通" or record["line"] == "电信": + retMsg = cloud.del_record(domain, record["id"]) + if(retMsg["code"] == 0): + log_cf2dns.logger.info("DELETE DNS SUCCESS: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+record["line"] ) + else: + log_cf2dns.logger.error("DELETE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+record["line"] + "----MESSAGE: " + retMsg["message"] ) + ret = cloud.get_record(domain, 100, sub_domain, recordType) + if DNS_SERVER != 1 or ret["code"] == 0 : + if DNS_SERVER == 1 and "Free" in ret["data"]["domain"]["grade"] and AFFECT_NUM > 2: + AFFECT_NUM = 2 + cm_info = [] + cu_info = [] + ct_info = [] + ab_info = [] + def_info = [] for record in ret["data"]["records"]: - if record["line"] == "移动" or record["line"] == "联通" or record["line"] == "电信": - retMsg = cloud.del_record( - domain, record["id"]) - if (retMsg["code"] == 0): - log_info( - f'DELETE DNS SUCCESS - DOMAIN: {domain} SUBDOMAIN: {sub_domain} RECORDLINE: {record["line"]}') - else: - traceback.print_exc() - log_error( - f'DELETE DNS ERROR - DOMAIN: {domain} SUBDOMAIN: {sub_domain} RECORDLINE: {record["line"]} MESSAGE: {retMsg["message"]}') - - # 重新创建对应 recordType 的 record - ret = cloud.get_record( - domain, 100, sub_domain, RECORD_TYPE) - - if DNS_SERVER == 1 and "DP_Free" in ret["data"]["domain"]["grade"] and AFFECT_NUM > 2: - AFFECT_NUM = 2 - - for line in lines: - if line == "CM": - changeDNS("CM", cf_cmips, - domain, sub_domain, cloud) - elif line == "CU": - changeDNS("CU", cf_cuips, - domain, sub_domain, cloud) - elif line == "CT": - changeDNS("CT", cf_ctips, - domain, sub_domain, cloud) - elif line == "AB": - changeDNS("AB", cf_ctips, - domain, sub_domain, cloud) - elif line == "DEF": - changeDNS("DEF", cf_ctips, - domain, sub_domain, cloud) + info = {} + info["recordId"] = record["id"] + info["value"] = record["value"] + if record["line"] == "移动": + cm_info.append(info) + elif record["line"] == "联通": + cu_info.append(info) + elif record["line"] == "电信": + ct_info.append(info) + elif record["line"] == "境外": + ab_info.append(info) + elif record["line"] == "默认": + def_info.append(info) + for line in lines: + if line == "CM": + changeDNS("CM", cm_info, temp_cf_cmips, domain, sub_domain, cloud) + elif line == "CU": + changeDNS("CU", cu_info, temp_cf_cuips, domain, sub_domain, cloud) + elif line == "CT": + changeDNS("CT", ct_info, temp_cf_ctips, domain, sub_domain, cloud) + elif line == "AB": + changeDNS("AB", ab_info, temp_cf_abips, domain, sub_domain, cloud) + elif line == "DEF": + changeDNS("DEF", def_info, temp_cf_defips, domain, sub_domain, cloud) except Exception as e: - traceback.print_exc() - log_error(f'CHANGE DNS ERROR - MESSAGE: {str(e)}') - + traceback.print_exc() + log_cf2dns.logger.error("CHANGE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----MESSAGE: " + str(e)) if __name__ == '__main__': if DNS_SERVER == 1: @@ -191,4 +191,4 @@ def main(cloud): cloud = AliApi(SECRETID, SECRETKEY, REGION_ALI) elif DNS_SERVER == 3: cloud = HuaWeiApi(SECRETID, SECRETKEY, REGION_HW) - main(cloud) + main(cloud) \ No newline at end of file diff --git a/cf2dns_actions.py b/cf2dns_actions.py index 52d9b41282d..a13d09fc3b2 100644 --- a/cf2dns_actions.py +++ b/cf2dns_actions.py @@ -1,60 +1,34 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- # Mail: tongdongdong@outlook.com import random import time -import os -import sys +import json import requests -from dns.qCloud import QcloudApiv3 # QcloudApiv3 DNSPod 的 API 更新了... +import os +import traceback +from dns.qCloud import QcloudApiv3 # QcloudApiv3 DNSPod 的 API 更新了 github@z0z0r4 from dns.aliyun import AliApi from dns.huawei import HuaWeiApi -import logging -import traceback -import json import sys - -log_cf2dns = logging.basicConfig(filename='cf2dns.log', - format='%(asctime)s - %(levelname)s - %(message)s', - level=logging.INFO, datefmt="%Y-%m-%d %H:%M:%S") - - -def log_error(msg: str): - logging.error(msg) - print( - f'[Error] [{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}] {msg}') - - -def log_info(msg: str): - logging.info(msg) - print( - f'[INFO] [{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}] {msg}') - - -# 可以从https://shop.hostmonit.com获取 -try: - KEY = os.environ["KEY"] -except KeyError: - KEY = "o1zrmHAF" -# CM:移动 CU:联通 CT:电信 AB:境外 DEF:默认 -# 修改需要更改的 DNSPod 域名和子域名 -# {"hostmonit.com": {"@": ["CM","CU","CT"], "shop": ["CM", "CU", "CT"], "stock": ["CM","CU","CT"]},"4096.me": {"@": ["CM","CU","CT"], "vv": ["CM","CU","CT"]}} -DOMAINS = json.loads(os.environ["DOMAINS"]) -# 腾讯云后台获取 https://console.cloud.tencent.com/cam/capi -SECRETID = os.environ["SECRETID"] # 'AKIDV**********Hfo8CzfjgN' -SECRETKEY = os.environ["SECRETKEY"] # 'ZrVs*************gqjOp1zVl' -# 默认为普通版本 不用修改 +#可以从https://shop.hostmonit.com获取 +KEY = os.environ["KEY"] #"o1zrmHAF" +#CM:移动 CU:联通 CT:电信 AB:境外 DEF:默认 +#修改需要更改的dnspod域名和子域名 +DOMAINS = json.loads(os.environ["DOMAINS"]) #{"hostmonit.com": {"@": ["CM","CU","CT"], "shop": ["CM", "CU", "CT"], "stock": ["CM","CU","CT"]},"4096.me": {"@": ["CM","CU","CT"], "vv": ["CM","CU","CT"]}} +#腾讯云后台获取 https://console.cloud.tencent.com/cam/capi +SECRETID = os.environ["SECRETID"] #'AKIDV**********Hfo8CzfjgN' +SECRETKEY = os.environ["SECRETKEY"] #'ZrVs*************gqjOp1zVl' +#默认为普通版本 不用修改 AFFECT_NUM = 2 -# DNS服务商 如果使用DNSPod改为1 如果使用阿里云解析改成2 如果使用华为云解析改成3 +#DNS服务商 如果使用DNSPod改为1 如果使用阿里云解析改成2 如果使用华为云解析改成3 DNS_SERVER = 1 -# 如果试用华为云解析 需要从API凭证-项目列表中获取 +#如果试用华为云解析 需要从API凭证-项目列表中获取 REGION_HW = 'cn-east-3' -# 如果使用阿里云解析 REGION出现错误再修改 默认不需要修改 https://help.aliyun.com/document_detail/198326.html +#如果使用阿里云解析 REGION出现错误再修改 默认不需要修改 https://help.aliyun.com/document_detail/198326.html REGION_ALI = 'cn-hongkong' -# 解析生效时间,默认为600秒 如果不是DNS付费版用户 不要修改!!! +#解析生效时间,默认为600秒 如果不是DNS付费版用户 不要修改!!! TTL = 600 -# A为筛选出IPv4的IP AAAA为筛选出IPv6的IP +#v4为筛选出IPv4的IP v6为筛选出IPv6的IP if len(sys.argv) >= 2: RECORD_TYPE = sys.argv[1] else: @@ -63,108 +37,149 @@ def log_info(msg: str): def get_optimization_ip(): try: - response = requests.post('https://api.hostmonit.com/get_optimization_ip', json={ - "key": KEY, "type": "v4" if RECORD_TYPE == "A" else "v6"}, headers={'Content-Type': 'application/json'}) + headers = headers = {'Content-Type': 'application/json'} + data = {"key": KEY, "type": "v4" if RECORD_TYPE == "A" else "v6"} + response = requests.post('https://api.hostmonit.com/get_optimization_ip', json=data, headers=headers) if response.status_code == 200: - resp_json = response.json() - if resp_json["code"] == 200: - return resp_json - else: - log_error(f'获取 Cloudflare IP 失败 Code: {resp_json["code"]} {resp_json["info"]}') + return response.json() else: - log_error(f'获取 Cloudflare IP 失败 {response.status_code}') + print("CHANGE OPTIMIZATION IP ERROR: REQUEST STATUS CODE IS NOT 200") + return None except Exception as e: - traceback.print_exc() - log_error(f"获取 Cloudflare IP 失败 {str(e)}") - + print("CHANGE OPTIMIZATION IP ERROR: " + str(e)) + return None -def changeDNS(line, c_info, domain, sub_domain, cloud): +def changeDNS(line, s_info, c_info, domain, sub_domain, cloud): global AFFECT_NUM, RECORD_TYPE lines = {"CM": "移动", "CU": "联通", "CT": "电信", "AB": "境外", "DEF": "默认"} line = lines[line] try: - create_num = AFFECT_NUM - for i in range(create_num): - if len(c_info) == 0: - break - cf_ip = c_info.pop(random.randint(0, len(c_info)-1))["ip"] - cloud.create_record( - domain, sub_domain, cf_ip, RECORD_TYPE, line, TTL) - log_info( - f'CREATE DNS SUCCESS - DOMAIN: {domain} SUBDOMAIN: {sub_domain} RECORDLINE: {line} VALUE: {cf_ip}') + create_num = AFFECT_NUM - len(s_info) + if create_num == 0: + for info in s_info: + if len(c_info) == 0: + break + cf_ip = c_info.pop(random.randint(0,len(c_info)-1))["ip"] + if cf_ip in str(s_info): + continue + ret = cloud.change_record(domain, info["recordId"], sub_domain, cf_ip, RECORD_TYPE, line, TTL) + if(DNS_SERVER != 1 or ret["code"] == 0): + print("CHANGE DNS SUCCESS: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip ) + else: + print("CHANGE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip + "----MESSAGE: " + ret["message"] ) + elif create_num > 0: + for i in range(create_num): + if len(c_info) == 0: + break + cf_ip = c_info.pop(random.randint(0,len(c_info)-1))["ip"] + if cf_ip in str(s_info): + continue + ret = cloud.create_record(domain, sub_domain, cf_ip, RECORD_TYPE, line, TTL) + if(DNS_SERVER != 1 or ret["code"] == 0): + print("CREATE DNS SUCCESS: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----VALUE: " + cf_ip ) + else: + print("CREATE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip + "----MESSAGE: " + ret["message"] ) + else: + for info in s_info: + if create_num == 0 or len(c_info) == 0: + break + cf_ip = c_info.pop(random.randint(0,len(c_info)-1))["ip"] + if cf_ip in str(s_info): + create_num += 1 + continue + ret = cloud.change_record(domain, info["recordId"], sub_domain, cf_ip, RECORD_TYPE, line, TTL) + if(DNS_SERVER != 1 or ret["code"] == 0): + print("CHANGE DNS SUCCESS: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip ) + else: + print("CHANGE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+line+"----RECORDID: " + str(info["recordId"]) + "----VALUE: " + cf_ip + "----MESSAGE: " + ret["message"] ) + create_num += 1 except Exception as e: - traceback.print_exc() - log_error(f'CHANGE DNS ERROR - MESSAGE: {str(e)}') - + print("CHANGE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----MESSAGE: " + str(traceback.print_exc())) def main(cloud): global AFFECT_NUM, RECORD_TYPE if len(DOMAINS) > 0: try: cfips = get_optimization_ip() - if cfips == None: - log_error(f'GET CLOUDFLARE IP ERROR') + if cfips == None or cfips["code"] != 200: + print("GET CLOUDFLARE IP ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) ) return cf_cmips = cfips["info"]["CM"] cf_cuips = cfips["info"]["CU"] cf_ctips = cfips["info"]["CT"] for domain, sub_domains in DOMAINS.items(): for sub_domain, lines in sub_domains.items(): - # 删除对应 recordType 的解析 - ret = cloud.get_record(domain, 20, sub_domain, RECORD_TYPE) - if ret["code"] == 0: + temp_cf_cmips = cf_cmips.copy() + temp_cf_cuips = cf_cuips.copy() + temp_cf_ctips = cf_ctips.copy() + temp_cf_abips = cf_ctips.copy() + temp_cf_defips = cf_ctips.copy() + if DNS_SERVER == 1: + ret = cloud.get_record(domain, 20, sub_domain, "CNAME") + if ret["code"] == 0: + for record in ret["data"]["records"]: + if record["line"] == "移动" or record["line"] == "联通" or record["line"] == "电信": + retMsg = cloud.del_record(domain, record["id"]) + if(retMsg["code"] == 0): + print("DELETE DNS SUCCESS: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+record["line"] ) + else: + print("DELETE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----DOMAIN: " + domain + "----SUBDOMAIN: " + sub_domain + "----RECORDLINE: "+record["line"] + "----MESSAGE: " + retMsg["message"] ) + ret = cloud.get_record(domain, 100, sub_domain, RECORD_TYPE) + if DNS_SERVER != 1 or ret["code"] == 0 : + if DNS_SERVER == 1 and "Free" in ret["data"]["domain"]["grade"] and AFFECT_NUM > 2: + AFFECT_NUM = 2 + cm_info = [] + cu_info = [] + ct_info = [] + ab_info = [] + def_info = [] for record in ret["data"]["records"]: - if record["line"] == "移动" or record["line"] == "联通" or record["line"] == "电信": - retMsg = cloud.del_record( - domain, record["id"]) - if (retMsg["code"] == 0): - log_info( - f'DELETE DNS SUCCESS - DOMAIN: {domain} SUBDOMAIN: {sub_domain} RECORDLINE: {record["line"]}') - else: - traceback.print_exc() - log_error( - f'DELETE DNS ERROR - DOMAIN: {domain} SUBDOMAIN: {sub_domain} RECORDLINE: {record["line"]} MESSAGE: {retMsg["message"]}') - - # 重新创建对应 recordType 的 record - ret = cloud.get_record( - domain, 100, sub_domain, RECORD_TYPE) - - if DNS_SERVER == 1 and "DP_Free" in ret["data"]["domain"]["grade"] and AFFECT_NUM > 2: - AFFECT_NUM = 2 - - for line in lines: - if line == "CM": - changeDNS("CM", cf_cmips, - domain, sub_domain, cloud) - elif line == "CU": - changeDNS("CU", cf_cuips, - domain, sub_domain, cloud) - elif line == "CT": - changeDNS("CT", cf_ctips, - domain, sub_domain, cloud) - elif line == "AB": - changeDNS("AB", cf_ctips, - domain, sub_domain, cloud) - elif line == "DEF": - changeDNS("DEF", cf_ctips, - domain, sub_domain, cloud) + if record["line"] == "移动": + info = {} + info["recordId"] = record["id"] + info["value"] = record["value"] + cm_info.append(info) + if record["line"] == "联通": + info = {} + info["recordId"] = record["id"] + info["value"] = record["value"] + cu_info.append(info) + if record["line"] == "电信": + info = {} + info["recordId"] = record["id"] + info["value"] = record["value"] + ct_info.append(info) + if record["line"] == "境外": + info = {} + info["recordId"] = record["id"] + info["value"] = record["value"] + ab_info.append(info) + if record["line"] == "默认": + info = {} + info["recordId"] = record["id"] + info["value"] = record["value"] + def_info.append(info) + for line in lines: + if line == "CM": + changeDNS("CM", cm_info, temp_cf_cmips, domain, sub_domain, cloud) + elif line == "CU": + changeDNS("CU", cu_info, temp_cf_cuips, domain, sub_domain, cloud) + elif line == "CT": + changeDNS("CT", ct_info, temp_cf_ctips, domain, sub_domain, cloud) + elif line == "AB": + changeDNS("AB", ab_info, temp_cf_abips, domain, sub_domain, cloud) + elif line == "DEF": + changeDNS("DEF", def_info, temp_cf_defips, domain, sub_domain, cloud) except Exception as e: - traceback.print_exc() - log_error(f'CHANGE DNS ERROR - MESSAGE: {str(e)}') - + print("CHANGE DNS ERROR: ----Time: " + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "----MESSAGE: " + str(traceback.print_exc())) if __name__ == '__main__': - try: - import requests - except: - os.system("pip install requests") - if DNS_SERVER == 1: cloud = QcloudApiv3(SECRETID, SECRETKEY) elif DNS_SERVER == 2: cloud = AliApi(SECRETID, SECRETKEY, REGION_ALI) elif DNS_SERVER == 3: cloud = HuaWeiApi(SECRETID, SECRETKEY, REGION_HW) - main(cloud) + main(cloud) \ No newline at end of file diff --git a/dns/qCloud.py b/dns/qCloud.py index 5f54c9152db..d8720137fd5 100644 --- a/dns/qCloud.py +++ b/dns/qCloud.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- # Mail: tongdongdong@outlook.com # Reference: https://cloud.tencent.com/document/product/302/8517 +# QcloudApiv3 DNSPod 的 API 更新了 By github@z0z0r4 import json from tencentcloud.common import credential @@ -44,7 +45,8 @@ def format_record(record: dict): params = { "Domain": domain, "Subdomain": sub_domain, - "RecordType": record_type + "RecordType": record_type, + "Limit": length } req_model.from_json_string(json.dumps(params)) diff --git a/log.py b/log.py new file mode 100644 index 00000000000..acb3fcd5ce7 --- /dev/null +++ b/log.py @@ -0,0 +1,38 @@ +import logging +from logging import handlers + +class Logger(object): + level_relations = { + 'debug':logging.DEBUG, + 'info':logging.INFO, + 'warning':logging.WARNING, + 'error':logging.ERROR, + 'crit':logging.CRITICAL + }#日志级别关系映射 + + def __init__(self,filename,level='info',when='D',backCount=3,fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'): + self.logger = logging.getLogger(filename) + format_str = logging.Formatter(fmt)#设置日志格式 + self.logger.setLevel(self.level_relations.get(level))#设置日志级别 + sh = logging.StreamHandler()#往屏幕上输出 + sh.setFormatter(format_str) #设置屏幕上显示的格式 + th = handlers.TimedRotatingFileHandler(filename=filename,when=when,backupCount=backCount,encoding='utf-8')#往文件里写入#指定间隔时间自动生成文件的处理器 + #实例化TimedRotatingFileHandler + #interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种: + # S 秒 + # M 分 + # H 小时、 + # D 天、 + # W 每星期(interval==0时代表星期一) + # midnight 每天凌晨 + th.setFormatter(format_str)#设置文件里写入的格式 + self.logger.addHandler(sh) #把对象加到logger里 + self.logger.addHandler(th) +if __name__ == '__main__': + log = Logger('monitor.log',level='debug') + log.logger.debug('debug') + log.logger.info('info') + log.logger.warning('警告') + log.logger.error('报错') + log.logger.critical('严重') + Logger('error.log', level='error').logger.error('error') \ No newline at end of file