فهرست منبع

Add CloudFlare to DDNS Module & Unify Naming

兔姬桑 4 سال پیش
والد
کامیت
119348ad8b

+ 4 - 1
app/Components/DDNS.php

@@ -3,6 +3,7 @@
 namespace App\Components;
 
 use App\Components\DDNS\Aliyun;
+use App\Components\DDNS\CloudFlare;
 use App\Components\DDNS\DNSPod;
 use App\Components\DDNS\Namesilo;
 use Log;
@@ -30,11 +31,13 @@ class DDNS
     {
         switch (sysConfig('ddns_mode')) {
             case 'aliyun':
-                return (new Aliyun($domain));
+                return new Aliyun($domain);
             case 'namesilo':
                 return new Namesilo($domain);
             case 'dnspod':
                 return new DNSPod($domain);
+            case 'cloudflare':
+                return new CloudFlare($domain);
             default:
                 Log::error("未知渠道:".sysConfig('ddns_mode'));
 

+ 5 - 4
app/Components/DDNS/Aliyun.php

@@ -27,7 +27,7 @@ class Aliyun
         return false;
     }
 
-    protected function analysisDomain()
+    private function analysisDomain()
     {
         $domainList = $this->domainList();
         if ($domainList) {
@@ -68,7 +68,7 @@ class Aliyun
         $parameters = array_merge(['Action' => $action], $data, $public);
         $parameters['Signature'] = $this->computeSignature($parameters);
 
-        $response = Http::timeout(15)->post(self::$apiHost.http_build_query($parameters));
+        $response = Http::asForm()->timeout(15)->post(self::$apiHost, $parameters);
         $message = $response->json();
 
         if ($response->failed()) {
@@ -118,9 +118,10 @@ class Aliyun
         if ($type) {
             $parameters['Type'] = $type;
         }
-        $records = $this->send('DescribeSubDomainRecords', $parameters)['DomainRecords']['Record'];
+        $records = $this->send('DescribeSubDomainRecords', $parameters);
 
-        if ($records) {
+        if ($records && Arr::has($records, 'DomainRecords.Record')) {
+            $records = $records['DomainRecords']['Record'];
             $data = null;
             foreach ($records as $record) {
                 $data[] = $record['RecordId'];

+ 128 - 0
app/Components/DDNS/CloudFlare.php

@@ -0,0 +1,128 @@
+<?php
+
+namespace App\Components\DDNS;
+
+use Arr;
+use Http;
+use Log;
+
+class CloudFlare
+{
+    private static $apiHost = 'https://api.cloudflare.com/client/v4/';
+    private static $subDomain;
+    private $zoneIdentifier;
+    private $client;
+
+    public function __construct($subDomain)
+    {
+        self::$subDomain = $subDomain;
+        $this->zoneIdentifier = $this->getZone();
+        $this->client = Http::withHeaders(['X-Auth-Key' => sysConfig('ddns_secret'), 'X-Auth-Email' => sysConfig('ddns_key')]);
+    }
+
+    private function getZone()
+    {
+        $zoneInfo = $this->client->get(self::$apiHost.'zones')->json();
+        if ($zoneInfo && Arr::has($zoneInfo, 'result.0.id')) {
+            $zones = $zoneInfo['result'];
+            foreach ($zones as $zone) {
+                if (strpos(self::$subDomain, $zone['name']) !== false) {
+                    return [$zone['name'], rtrim(substr(self::$subDomain, 0, -(strlen($zone['name']))), '.'), $zone['id']];
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public function store($ip, $type)
+    {
+        if ($this->zoneIdentifier) {
+            return $this->send('create', ['type' => $type, 'name' => self::$subDomain, 'content' => $ip, 'ttl' => 120]);
+        }
+
+        return false;
+    }
+
+    private function send($action, $data = [], $id = null)
+    {
+        if ($this->zoneIdentifier) {
+            switch ($action) {
+                case 'get':
+                    $response = $this->client->get(self::$apiHost.'zones/'.$this->zoneIdentifier[2].'/dns_records', $data);
+                    break;
+                case 'create':
+                    $response = $this->client->post(self::$apiHost.'zones/'.$this->zoneIdentifier[2].'/dns_records', $data);
+                    break;
+                case 'update':
+                    $response = $this->client->put(self::$apiHost.'zones/'.$this->zoneIdentifier[2].'/dns_records/'.$id,
+                        $data);
+                    break;
+                case 'delete':
+                    $response = $this->client->delete(self::$apiHost.'zones/'.$this->zoneIdentifier[2].'/dns_records/'.$id);
+                    break;
+                default:
+                    return false;
+            }
+
+            $message = $response->json();
+            if ($message && !$response->failed()) {
+                return $message;
+            }
+
+            Log::error('[CloudFlare API] - ['.$action.'] 请求失败:'.var_export($message, true));
+        }
+
+        return false;
+    }
+
+    public function update($ip, $type)
+    {
+        $recordId = $this->getRecordId($type);
+
+        if ($this->zoneIdentifier && $recordId) {
+            return $this->send('update', ['type' => $type, 'name' => self::$subDomain, 'content' => $ip, 'ttl' => 120], $recordId[0]);
+        }
+
+        return false;
+    }
+
+    private function getRecordId($type = null)
+    {
+        $parameters['name'] = self::$subDomain;
+        if ($type) {
+            $parameters['type'] = $type;
+        }
+        $dnsList = $this->send('get', $parameters);
+
+        if ($dnsList && Arr::has($dnsList, 'result.0.id')) {
+            $dnsRecords = $dnsList['result'];
+            $data = null;
+            foreach ($dnsRecords as $record) {
+                $data[] = $record['id'];
+            }
+
+            return $data ?: false;
+        }
+
+        return false;
+    }
+
+    public function destroy($type)
+    {
+        $records = $this->getRecordId($type);
+        if ($records && $this->zoneIdentifier) {
+            $count = 0;
+            foreach ($records as $record) {
+                $result = $this->send('delete', [], $record);
+                if ($result && Arr::has($result, 'result.id')) {
+                    $count++;
+                }
+            }
+
+            return $count;
+        }
+
+        return false;
+    }
+}

+ 25 - 25
app/Components/DDNS/DNSPod.php

@@ -33,7 +33,7 @@ class DNSPod
         return false;
     }
 
-    public function analysisDomain()
+    private function analysisDomain()
     {
         $domainList = $this->domainList();
         if ($domainList) {
@@ -82,26 +82,25 @@ class DNSPod
         return $message;
     }
 
-    public function destroy($type)
+    public function update($ip, $type)
     {
-        $records = $this->getRecordId($type);
+        $recordId = $this->getRecordId($type);
         $domainInfo = $this->analysisDomain();
-        if ($records && $domainInfo) {
-            $count = 0;
-            foreach ($records as $record) {
-                $result = $this->send('Record.Remove', ['domain_id' => $domainInfo[2], 'record_id' => $record]);
-                if ($result) {
-                    $count++;
-                }
-            }
-
-            return $count;
+        if ($recordId && $domainInfo) {
+            return $this->send('Record.Modify', [
+                'domain_id'      => $domainInfo[2],
+                'record_id'      => $recordId[0],
+                'sub_domain'     => $domainInfo[1],
+                'record_type'    => $type,
+                'record_line_id' => 0,
+                'value'          => $ip,
+            ]);
         }
 
         return false;
     }
 
-    public function getRecordId($type = null)
+    private function getRecordId($type = null)
     {
         $domainInfo = $this->analysisDomain();
         if ($domainInfo) {
@@ -118,19 +117,20 @@ class DNSPod
         return false;
     }
 
-    public function update($ip, $type)
+    public function destroy($type)
     {
-        $recordId = $this->getRecordId($type);
+        $records = $this->getRecordId($type);
         $domainInfo = $this->analysisDomain();
-        if ($recordId && $domainInfo) {
-            return $this->send('Record.Modify', [
-                'domain_id'      => $domainInfo[2],
-                'record_id'      => $recordId[0],
-                'sub_domain'     => $domainInfo[1],
-                'record_type'    => $type,
-                'record_line_id' => 0,
-                'value'          => $ip,
-            ]);
+        if ($records && $domainInfo) {
+            $count = 0;
+            foreach ($records as $record) {
+                $result = $this->send('Record.Remove', ['domain_id' => $domainInfo[2], 'record_id' => $record]);
+                if ($result) {
+                    $count++;
+                }
+            }
+
+            return $count;
         }
 
         return false;

+ 5 - 5
app/Components/DDNS/Namesilo.php

@@ -15,7 +15,7 @@ class Namesilo
         self::$subDomain = $subDomain;
     }
 
-    public function store($ip, $type = 'A')
+    public function store($ip, $type)
     {
         $domainInfo = $this->analysisDomain();
         if ($domainInfo) {
@@ -31,7 +31,7 @@ class Namesilo
         return false;
     }
 
-    protected function analysisDomain()
+    private function analysisDomain()
     {
         $domainList = $this->domainList();
         if ($domainList) {
@@ -59,7 +59,7 @@ class Namesilo
         return false;
     }
 
-    private function send($operation, $data = [])
+    private function send($action, $data = [])
     {
         $params = [
             'version' => 1,
@@ -68,14 +68,14 @@ class Namesilo
         ];
         $query = array_merge($params, $data);
 
-        $result = file_get_contents(self::$apiHost.$operation.'?'.http_build_query($query));
+        $result = file_get_contents(self::$apiHost.$action.'?'.http_build_query($query));
         $result = json_decode(json_encode(simplexml_load_string(trim($result))), true);
 
         if ($result && $result['reply']['code'] === '300' && $result['reply']['detail'] === 'success') {
             return $result['reply'];
         }
 
-        Log::error('[Namesilo API] - ['.$operation.'] 请求失败:'.var_export($result, true));
+        Log::error('[Namesilo API] - ['.$action.'] 请求失败:'.var_export($result, true));
 
         return false;
     }

+ 1 - 1
config/version.php

@@ -2,5 +2,5 @@
 
 return [
     'name'   => 'ProxyPanel',
-    'number' => '2.5.a',
+    'number' => '2.5.b',
 ];

+ 1 - 0
resources/views/admin/config/system.blade.php

@@ -563,6 +563,7 @@
                                                 <option value="namesilo">Namesilo</option>
                                                 <option value="aliyun">阿里云(国际&国内)</option>
                                                 <option value="dnspod">DNSPod</option>
+                                                <option value="cloudflare">CloudFlare</option>
                                             </select>
                                             <span class="text-help offset-md-3"> 添加/编辑/删除节点的【域名、ipv4、ipv6】时,自动更新对应内容至DNS服务商 </span>
                                         </div>