diff --git a/app/controller/Domain.php b/app/controller/Domain.php index 0a79ab7..441f3c4 100644 --- a/app/controller/Domain.php +++ b/app/controller/Domain.php @@ -267,7 +267,7 @@ class Domain extends BaseController $recordLineArr = []; foreach($recordLine as $key=>$item){ - $recordLineArr[] = ['id'=>$key, 'name'=>$item['name'], 'parent'=>$item['parent']]; + $recordLineArr[] = ['id'=>strval($key), 'name'=>$item['name'], 'parent'=>$item['parent']]; } $dnsconfig = DnsHelper::$dns_config[$dnstype]; @@ -300,7 +300,7 @@ class Domain extends BaseController $recordLineArr = []; foreach($recordLine as $key=>$item){ - $recordLineArr[] = ['id'=>$key, 'name'=>$item['name'], 'parent'=>$item['parent']]; + $recordLineArr[] = ['id'=>strval($key), 'name'=>$item['name'], 'parent'=>$item['parent']]; } $dnsconfig = DnsHelper::$dns_config[$dnstype]; diff --git a/app/lib/DnsHelper.php b/app/lib/DnsHelper.php index 48dd544..34fb727 100644 --- a/app/lib/DnsHelper.php +++ b/app/lib/DnsHelper.php @@ -50,6 +50,17 @@ class DnsHelper 'redirect' => false, 'log' => false, ], + 'dnsla' => [ + 'name' => 'DNSLA', + 'config' => [ + 'ak' => 'APIID', + 'sk' => 'API密钥' + ], + 'remark' => 0, + 'status' => true, + 'redirect' => true, + 'log' => false, + ], 'cloudflare' => [ 'name' => 'Cloudflare', 'config' => [ @@ -57,7 +68,7 @@ class DnsHelper 'sk' => 'API密钥' ], 'remark' => 2, - 'status' => false, + 'status' => true, 'redirect' => false, 'log' => false, ], diff --git a/app/lib/dns/baidu.php b/app/lib/dns/baidu.php index aa16920..08bf3c2 100644 --- a/app/lib/dns/baidu.php +++ b/app/lib/dns/baidu.php @@ -7,8 +7,6 @@ class baidu implements DnsInterface { private $AccessKeyId; private $SecretAccessKey; private $endpoint = "dns.baidubce.com"; - private $service = "dnspod"; - private $version = "2021-03-23"; private $error; private $domain; private $domainid; diff --git a/app/lib/dns/dnsla.php b/app/lib/dns/dnsla.php new file mode 100644 index 0000000..dfbf155 --- /dev/null +++ b/app/lib/dns/dnsla.php @@ -0,0 +1,251 @@ + 'A', 2 => 'NS', 5 => 'CNAME', 15 => 'MX', 16 => 'TXT', 28 => 'AAAA', 33 => 'SRV', 257 => 'CAA', 256 => 'URL转发']; + private $error; + private $domain; + private $domainid; + + function __construct($config){ + $this->apiid = $config['ak']; + $this->apisecret = $config['sk']; + $this->domain = $config['domain']; + $this->domainid = $config['domainid']; + } + + public function getError(){ + return $this->error; + } + + public function check(){ + if($this->getDomainList() != false){ + return true; + } + return false; + } + + //获取域名列表 + public function getDomainList($KeyWord=null, $PageNumber=1, $PageSize=20){ + $param = ['pageIndex' => $PageNumber, 'pageSize' => $PageSize]; + $data = $this->execute('GET', '/api/domainList', $param); + if($data){ + $list = []; + foreach($data['results'] as $row){ + $list[] = [ + 'DomainId' => $row['id'], + 'Domain' => rtrim($row['displayDomain'], '.'), + 'RecordCount' => 0, + ]; + } + return ['total' => $data['total'], 'list' => $list]; + } + return false; + } + + //获取解析记录列表 + public function getDomainRecords($PageNumber=1, $PageSize=20, $KeyWord = null, $SubDomain = null, $Type = null, $Line = null, $Status = null){ + $param = ['domainId' => $this->domainid, 'pageIndex' => $PageNumber, 'pageSize' => $PageSize]; + if(!isNullOrEmpty(($KeyWord))){ + $param['host'] = $KeyWord; + } + if(!isNullOrEmpty(($Type))){ + $param['type'] = $this->convertType($Type); + } + if(!isNullOrEmpty(($Line))){ + $param['lineId'] = $Line; + } + if(!isNullOrEmpty(($SubDomain))){ + $param['host'] = $SubDomain; + } + $data = $this->execute('GET', '/api/recordList', $param); + if($data){ + $list = []; + foreach($data['results'] as $row){ + $list[] = [ + 'RecordId' => $row['id'], + 'Domain' => $this->domain, + 'Name' => $row['host'], + 'Type' => $this->convertTypeId($row['type'], isset($row['domaint']) ? $row['domaint'] : false), + 'Value' => $row['data'], + 'Line' => $row['lineId'], + 'TTL' => $row['ttl'], + 'MX' => isset($row['preference']) ? $row['preference'] : null, + 'Status' => $row['disable'] ? '0' : '1', + 'Weight' => isset($row['weight']) ? $row['weight'] : null, + 'Remark' => null, + 'UpdateTime' => date('Y-m-d H:i:s', $row['updatedAt']), + ]; + } + return ['total' => $data['total'], 'list' => $list]; + } + return false; + } + + //获取子域名解析记录列表 + public function getSubDomainRecords($SubDomain, $PageNumber=1, $PageSize=20, $Type = null, $Line = null){ + $domain_arr = explode('.', $SubDomain); + $domain = $domain_arr[count($domain_arr)-2].'.'.$domain_arr[count($domain_arr)-1]; + $subdomain = rtrim(str_replace($domain,'',$SubDomain),'.'); + if($subdomain == '')$subdomain='@'; + return $this->getDomainRecords($PageNumber, $PageSize, null, $subdomain, $Type, $Line); + } + + //获取解析记录详细信息 + public function getDomainRecordInfo($RecordId){ + return false; + } + + //添加解析记录 + public function addDomainRecord($Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){ + $param = ['domainId' => $this->domainid, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line]; + if($Type == 'MX')$param['preference'] = intval($MX); + if($Type == 'REDIRECT_URL'){$param['type'] = 256;$param['dominant'] = true;} + elseif($Type == 'FORWARD_URL'){$param['type'] = 256;$param['dominant'] = false;} + $data = $this->execute('POST', '/api/record', $param); + return is_array($data) ? $data['id'] : false; + } + + //修改解析记录 + public function updateDomainRecord($RecordId, $Name, $Type, $Value, $Line = '0', $TTL = 600, $MX = 1, $Remark = null){ + $param = ['id' => $RecordId, 'type' => $this->convertType($Type), 'host' => $Name, 'data' => $Value, 'ttl' => intval($TTL), 'lineId' => $Line]; + if($Type == 'MX')$param['preference'] = intval($MX); + if($Type == 'REDIRECT_URL'){$param['type'] = 256;$param['dominant'] = true;} + elseif($Type == 'FORWARD_URL'){$param['type'] = 256;$param['dominant'] = false;} + $data = $this->execute('PUT', '/api/record', $param); + return $data!==false; + } + + //修改解析记录备注 + public function updateDomainRecordRemark($RecordId, $Remark){ + return false; + } + + //删除解析记录 + public function deleteDomainRecord($RecordId){ + $param = ['id' => $RecordId]; + $data = $this->execute('DELETE', '/api/record', $param); + return $data!==false; + } + + //设置解析记录状态 + public function setDomainRecordStatus($RecordId, $Status){ + $param = ['id' => $RecordId, 'disable' => $Status == '0' ? true : false]; + $data = $this->execute('PUT', '/api/recordDisable', $param); + return $data!==false; + } + + //获取解析记录操作日志 + public function getDomainRecordLog($PageNumber = 1, $PageSize = 20, $KeyWord = null, $StartDate = null, $endDate = null){ + return false; + } + + //获取解析线路列表 + public function getRecordLine(){ + $param = ['domain' => $this->domain]; + $data = $this->execute('GET', '/api/availableLine', $param); + if($data){ + array_multisort(array_column($data, 'order'), SORT_ASC, $data); + $list = []; + foreach($data as $row){ + if($row['id'] == '0') $row['id'] = ''; + $list[$row['id']] = ['name'=>$row['value'], 'parent'=>!empty($row['pid']) ? $row['pid'] : null]; + } + return $list; + } + return false; + } + + //获取域名信息 + public function getDomainInfo(){ + $param = ['id' => $this->domainid]; + $data = $this->execute('GET', '/api/domain', $param); + return $data; + } + + //获取域名最低TTL + public function getMinTTL(){ + $param = ['id' => $this->domainid]; + $data = $this->execute('GET', '/api/dnsMeasures', $param); + if($data && isset($data['minTTL'])){ + return $data['minTTL']; + } + return false; + } + + private function convertType($type){ + $typeList = array_flip($this->typeList); + return $typeList[$type]; + } + + private function convertTypeId($typeId, $domaint){ + if($typeId == 256) return $domaint ? 'REDIRECT_URL' : 'FORWARD_URL'; + return $this->typeList[$typeId]; + } + + private function execute($method, $path, $params = null){ + $token = base64_encode($this->apiid.':'.$this->apisecret); + $header = ['Authorization: Basic '.$token, 'Content-Type: application/json; charset=utf-8']; + if($method == 'POST' || $method == 'PUT'){ + $response = $this->curl($method, $path, $header, json_encode($params)); + }else{ + if($params){ + $path .= '?'.http_build_query($params); + } + $response = $this->curl($method, $path, $header); + } + $arr=json_decode($response,true); + if($arr){ + if($arr['code'] == 200){ + return $arr['data']; + }else{ + $this->setError($arr['msg']); + return false; + } + }else{ + $this->setError('返回数据解析失败'); + return false; + } + } + + private function curl($method, $path, $header, $body = null, $isPut = false){ + $url = $this->baseUrl . $path; + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + if ($body) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + } + $response = curl_exec($ch); + $errno = curl_errno($ch); + if ($errno) { + $this->setError('Curl error: ' . curl_error($ch)); + } + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + if ($errno) return false; + if($httpCode==200){ + return $response; + }elseif($httpCode==401){ + $this->setError('认证失败'); + return false; + }else{ + $this->setError('http code: '.$httpCode); + return false; + } + } + + private function setError($message){ + $this->error = $message; + //file_put_contents('logs.txt',date('H:i:s').' '.$message."\r\n", FILE_APPEND); + } +} \ No newline at end of file diff --git a/app/lib/dns/dnspod.php b/app/lib/dns/dnspod.php index 02f9c2e..28129a7 100644 --- a/app/lib/dns/dnspod.php +++ b/app/lib/dns/dnspod.php @@ -57,11 +57,11 @@ class dnspod implements DnsInterface { $action = 'DescribeRecordFilterList'; $Status = $Status == '1' ? 'ENABLE' : 'DISABLE'; $param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize, 'RecordStatus' => [$Status]]; - if(!isNullOrEmpty($Type)) $param['RecordType'] = [$Type]; + if(!isNullOrEmpty($Type)) $param['RecordType'] = [$this->convertType($Type)]; if(!isNullOrEmpty($Line)) $param['RecordLine'] = [$Line]; }else{ $action = 'DescribeRecordList'; - $param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'RecordType' => $Type, 'RecordLineId' => $Line, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize]; + $param = ['Domain' => $this->domain, 'Subdomain' => $SubDomain, 'RecordType' => $this->convertType($Type), 'RecordLineId' => $Line, 'Keyword' => $KeyWord, 'Offset' => $offset, 'Limit' => $PageSize]; } $data = $this->send_reuqest($action, $param); if($data){ @@ -72,7 +72,7 @@ class dnspod implements DnsInterface { 'RecordId' => $row['RecordId'], 'Domain' => $this->domain, 'Name' => $row['Name'], - 'Type' => $row['Type'], + 'Type' => $this->convertTypeId($row['Type']), 'Value' => $row['Value'], 'Line' => $row['LineId'], 'TTL' => $row['TTL'], @@ -107,7 +107,7 @@ class dnspod implements DnsInterface { 'RecordId' => $data['RecordInfo']['Id'], 'Domain' => $this->domain, 'Name' => $data['RecordInfo']['SubDomain'], - 'Type' => $data['RecordInfo']['RecordType'], + 'Type' => $this->convertTypeId($data['RecordInfo']['RecordType']), 'Value' => $data['RecordInfo']['Value'], 'Line' => $data['RecordInfo']['RecordLineId'], 'TTL' => $data['RecordInfo']['TTL'], @@ -266,6 +266,14 @@ class dnspod implements DnsInterface { return $type; } + private function convertTypeId($type){ + $convert_dict = ['显性URL'=>'REDIRECT_URL', '隐性URL'=>'FORWARD_URL']; + if(array_key_exists($type, $convert_dict)){ + return $convert_dict[$type]; + } + return $type; + } + private function send_reuqest($action, $param){ $param = array_filter($param, function($a){ return $a!==null;}); diff --git a/app/view/domain/record.html b/app/view/domain/record.html index d24ba86..bff7fdf 100644 --- a/app/view/domain/record.html +++ b/app/view/domain/record.html @@ -153,7 +153,12 @@ $(document).ready(function(){ }, { field: 'Type', - title: '记录类型' + title: '记录类型', + formatter: function(value, row, index) { + if(value == 'REDIRECT_URL') return '显性URL'; + if(value == 'FORWARD_URL') return '隐性URL'; + return value; + } }, { field: 'LineName', diff --git a/public/static/images/dnsla.ico b/public/static/images/dnsla.ico new file mode 100644 index 0000000..2689fad Binary files /dev/null and b/public/static/images/dnsla.ico differ