#coding: utf-8 # +------------------------------------------------------------------- # | 集群架构 - DNS管理模块 # +------------------------------------------------------------------- # | Copyright (c) 2015-2099 宝塔软件(https://bt.cn) All rights reserved. # +------------------------------------------------------------------- # | Author: hwliang # +------------------------------------------------------------------- import public,os,sys,json,time,random import requests # from OpenSSL import crypto import sys, os import time import copy import json import base64 import hashlib import binascii import urllib if sys.version_info[0] == 2: # python2 import urlparse from urlparse import urljoin import urllib2 import cryptography.hazmat import cryptography.hazmat.backends import cryptography.hazmat.primitives.serialization else: # python3 from urllib.parse import urlparse from urllib.parse import urljoin import cryptography import platform import hmac try: import requests except: public.ExecShell('pip install requests') import requests # try: # import OpenSSL # except: # public.ExecShell('pip install pyopenssl') # import OpenSSL import random import datetime import logging from hashlib import sha1 class clusterDns: def __init__(self): pass class aliyun: key = None secret = None url = "https://alidns.aliyuncs.com" def __init__(self, key, secret, ): self.key = str(key).strip() self.secret = str(secret).strip() def sign(self, parameters): ''' @name 签名 @author hwliang<2020-10-30> @param parameters 被签名的参数 @return string ''' def percent_encode(encodeStr): encodeStr = str(encodeStr) if sys.version_info[0] == 3: import urllib.request res = urllib.request.quote(encodeStr, '') else: res = urllib2.quote(encodeStr, '') res = res.replace('+', '%20') res = res.replace('*', '%2A') res = res.replace('%7E', '~') return res sortedParameters = sorted(parameters.items(), key=lambda parameters: parameters[0]) canonicalizedQueryString = '' for (k, v) in sortedParameters: canonicalizedQueryString += '&' + percent_encode(k) + '=' + percent_encode(v) stringToSign = 'GET&%2F&' + percent_encode(canonicalizedQueryString[1:]) if sys.version_info[0] == 2: h = hmac.new(self.secret + "&", stringToSign, sha1) signature = base64.encodestring(h.digest()).strip() else: h = hmac.new(bytes(self.secret + "&", encoding="utf8"), stringToSign.encode('utf8'), sha1) signature = base64.encodebytes(h.digest()).strip() return signature def get_params(self,action,pdata={}): ''' @name 构造请求参数 @author hwliang<2020-10-30> @param action 请求动作 @return dict ''' randomint = random.randint(11111111111111, 99999999999999) now = datetime.datetime.utcnow() otherStyleTime = now.strftime("%Y-%m-%dT%H:%M:%SZ") paramsdata = { "Action":action, "Format": "json", "Version": "2015-01-09", "SignatureMethod": "HMAC-SHA1", "Timestamp": otherStyleTime, "SignatureVersion": "1.0", "SignatureNonce": str(randomint), "Lang": 'cn', "AccessKeyId": self.key } for k in pdata.keys(): paramsdata[k] = pdata[k] paramsdata['Signature'] = self.sign(paramsdata) return paramsdata def check_result(self,req): ''' @name 检查响应结果 @author hwliang<2020-10-30> @param req 响应结果 @return mixed ''' result = req.json() if req.status_code != 200: if result['Code'] == 'IncorrectDomainUser' or result['Code'] == 'InvalidDomainName.NoExist': return public.returnMsg(False,"这个阿里云账户下面不存在这个域名") elif result['Code'] == 'InvalidAccessKeyId.NotFound' or result['Code'] == 'SignatureDoesNotMatch': return public.returnMsg(False,"API密钥错误") else: return public.returnMsg(False,result['Message']) return result def get_domain_list(self,args = None): ''' @name 获取域名列表 @author hwliang<2020-10-30> @param args 前端参数 @return list ''' paramsdata = self.get_params('DescribeDomains') req = requests.get(url=self.url, params=paramsdata,verify=False) result = self.check_result(req) return result def add_record(self,domain,s_type,host,value): ''' @name 添加解析记录 @author hwliang<2020-10-30> @param args 前端参数 @return list ''' paramsdata = {} paramsdata['DomainName'] = domain paramsdata['RR'] = host paramsdata['Type'] = s_type paramsdata['Value'] = value paramsdata = self.get_params('AddDomainRecord',paramsdata) req = requests.get(url=self.url, params=paramsdata,verify=False) result = self.check_result(req) if 'status' in result: if not result['status']: return result return public.returnMsg(True,'添加成功') def query_recored_items(self, domain, host=None, s_type=None, page=1, psize=200): ''' @name 获取解析列表 @author hwliang<2020-10-30> @param domain 域名 @param host 记录值关键词 @param s_type 记录类型关键词 @param page 分页 @param psize 每页行数 @return list ''' paramsdata = {} paramsdata['DomainName'] = domain paramsdata['PageNumber'] = page paramsdata['PageSize'] = psize if host: paramsdata['RRKeyWord'] = host if s_type: paramsdata['TypeKeyWord'] = s_type paramsdata = self.get_params('DescribeDomainRecords',paramsdata) req = requests.get(url=self.url, params=paramsdata,verify=False) result = self.check_result(req) return result def query_recored_id(self, domain, host, s_type="A"): ''' @name 获取解析标识 @author hwliang<2020-10-30> @param domain 域名 @param zone 记录值关键词 @param tipe 记录类型关键词 @return int or None ''' record_id = None recoreds = self.query_recored_items(domain, host, s_type=s_type) recored_list = recoreds.get("DomainRecords", {}).get("Record", []) recored_item_list = [i for i in recored_list if i["RR"] == host] if len(recored_item_list): record_id = recored_item_list[0]["RecordId"] return record_id def remove_record(self,domain,host,s_type = 'A'): ''' @name 删除解析记录 @author hwliang<2020-10-30> @param domain 域名 @param host 记录值关键词 @param s_type 记录类型关键词 @return dict ''' record_id = self.query_recored_id(domain,host,s_type) if not record_id: return public.returnMsg(False,"找不到域名的record_id: {}".format(domain)) paramsdata = {} paramsdata['RecordId'] = record_id paramsdata = self.get_params('DeleteDomainRecord',paramsdata) req = requests.get(url=self.url, params=paramsdata,verify=False) result = self.check_result(req) if 'status' in result: if not result['status']: return result return public.returnMsg(True,'删除成功') class dnspod: dns_provider_name = "dnspod" url = 'https://dnsapi.cn/' http_timeout = 60 dnspod_id = None dnspod_api_key = None dnspod_login = None def __init__(self, dnspod_id, dnspod_api_key): self.dnspod_id = dnspod_id self.dnspod_api_key = dnspod_api_key self.dnspod_login = "{0},{1}".format(self.dnspod_id, self.dnspod_api_key) def get_params(self): ''' @name 构造请求参数 @author hwliang<2020-10-30> @return dict ''' params = { "format": "json", "login_token": self.dnspod_login, "lang":'cn', "error_on_empty":'no' } return params def get_domain_list(self,args=None): ''' @name 域取域名列表 @author hwliang<2020-10-30> @return dict ''' url = urljoin(self.url, "Domain.List") params = self.get_params() req = requests.post(url, data=params, timeout=self.http_timeout).json() return req def get_record_list(self,domain): url = urljoin(self.url, "Record.List") params = self.get_params() params['domain'] = domain req = requests.post(url, data=params, timeout=self.http_timeout).json() return req def add_record(self,domain,host,value,s_type): url = urljoin(self.url, "Record.Create") params = self.get_params() params['record_type'] = s_type params['domain'] = domain params['sub_domain'] = host params['value'] = value params['record_line_id'] = '0' req = requests.post(url, data=params, timeout=self.http_timeout).json() if req["status"]["code"] != "1": raise ValueError( "Error creating dnspod dns record: status_code={status_code} response={response}".format( status_code=req["status"]["code"], response=req["status"]["message"], ) ) def remove_record(self,domain,host,s_type): url = urljoin(self.url, "Record.List") params = self.get_params() params['record_type'] = s_type params['domain'] = domain params['subdomain'] = host list_dns_response = requests.post(url, data=params, timeout=self.http_timeout).json() urlr = urljoin(self.url, "Record.Remove") for i in range(0, len(list_dns_response["records"])): if list_dns_response["records"][i]['name'] != host: continue record_id = list_dns_response["records"][i]["id"] params = self.get_params() params['domain'] = domain params['record_id'] = record_id requests.post(urlr, data=params, timeout=self.http_timeout).json()