From d62c25888dfa749edb31bdd78cd9fffcf1bdafd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=A4=80=ED=9D=A0?= Date: Fri, 11 Oct 2024 19:30:43 +0900 Subject: [PATCH] cfmgrv4 init...2 --- app/Config/Routes.php | 1 + app/Controllers/CLI/Cloudflare.php | 38 +++++++------ app/Language/en/Cloudflare/Zone.php | 3 +- app/Libraries/Cloudflare/Account.php | 33 ++++++++---- app/Libraries/Cloudflare/Cloudflare.php | 47 +++++++++------- app/Libraries/Cloudflare/Record.php | 29 ++++++---- app/Libraries/Cloudflare/Zone.php | 60 ++++++++++----------- app/Libraries/MySocket/CloudflareSocket.php | 6 +-- app/Libraries/MySocket/MySocket.php | 8 +-- app/Models/CommonModel.php | 6 +-- 10 files changed, 132 insertions(+), 99 deletions(-) diff --git a/app/Config/Routes.php b/app/Config/Routes.php index ade11ae..de5bb61 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -21,6 +21,7 @@ $routes->group('/user', function ($routes) { $routes->group('cli', ['namespace' => 'App\Controllers\CLI'], function ($routes) { $routes->group('cloudflare', function ($routes) { $routes->cli('reload', 'Cloudflare::reload'); + $routes->cli('reload/(:num)', 'Cloudflare::reload/$1'); }); }); $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'authFilter:manager'], function ($routes) { diff --git a/app/Controllers/CLI/Cloudflare.php b/app/Controllers/CLI/Cloudflare.php index 5c8772d..082c6fa 100644 --- a/app/Controllers/CLI/Cloudflare.php +++ b/app/Controllers/CLI/Cloudflare.php @@ -22,14 +22,17 @@ class Cloudflare extends BaseController parent::initController($request, $response, $logger); $this->_db = \Config\Database::connect(); } - private function getAuthModel(): AuthModel + private function auth_process(mixed $uid = false): array { - return new AuthModel(); - } - private function auth_process(): array - { - $this->getAuthModel()->where('status', DEFAULTS["STATUS"]); - return $this->getAuthModel()->getEntitys(); + $authModel = model(AuthModel::class); + if (is_numeric($uid) && $uid > 0) { + $authModel->where(AuthModel::PK, intval($uid)); + } else { + $authModel->where('status', DEFAULTS["STATUS"]); + } + $entitys = $authModel->getEntitys(); + log_message("debug", $authModel->getLastQuery()); + return $entitys; } private function account_process(AuthEntity $auth_entity): array { @@ -46,25 +49,26 @@ class Cloudflare extends BaseController $record = new Record($zone_entity); return $record->reload(); } - public function reload(): void + public function reload(mixed $uid = false): void { //Transaction Start $this->_db->transStart(); try { - $auths = $this->auth_process(); + $auths = $this->auth_process($uid); $accounts = []; foreach ($auths as $auth) { - $accounts = $this->account_process($auth); + $accounts += $this->account_process($auth); } + log_message("debug", "\n-------------총 Accounts:" . count($accounts) . "--------------------\n"); $zones = []; - foreach ($accounts as $account) { - $zones = $this->zone_process($account); + foreach ($accounts as $key => $account) { + $zones += $this->zone_process($account); } - $records = []; - foreach ($zones as $zone) { - $records = $this->record_process($zone); - } - log_message("notice", "Reload 작업을 완료하였습니다."); + log_message("debug", "\n-------------총 Zones:" . count($zones) . "--------------------\n"); + // foreach ($zones as $key => $zone) { + // $this->record_process($zone); + // } + // log_message("notice", "Reload 작업을 완료하였습니다."); $this->_db->transCommit(); } catch (\Exception $e) { //Transaction Rollback diff --git a/app/Language/en/Cloudflare/Zone.php b/app/Language/en/Cloudflare/Zone.php index a90261e..21cf430 100644 --- a/app/Language/en/Cloudflare/Zone.php +++ b/app/Language/en/Cloudflare/Zone.php @@ -36,8 +36,9 @@ return [ "essentially_off" => "essentially_off", ], "STATUS" => [ - "active" => "active", + "initializing" => "initializing", "pending" => "pending", + "active" => "active", "moved" => "moved" ], ]; diff --git a/app/Libraries/Cloudflare/Account.php b/app/Libraries/Cloudflare/Account.php index 30e657a..4d99041 100644 --- a/app/Libraries/Cloudflare/Account.php +++ b/app/Libraries/Cloudflare/Account.php @@ -4,6 +4,7 @@ namespace App\Libraries\Cloudflare; use App\Models\Cloudflare\AccountModel; use App\Entities\Cloudflare\AuthEntity; +use App\Entities\Cloudflare\AccountEntity; class Account extends Cloudflare { @@ -34,7 +35,8 @@ class Account extends Cloudflare // "legacy_flags":{"enterprise_zone_quota":{"maximum":0,"current":0,"available":0}}, // "created_on":"2017-06-26T05:44:49.470184Z"} // ] - public function getArrayByResult($result, array $formDatas = []): array + + protected function getArrayByResult($result, array $formDatas = []): array { $formDatas[AccountModel::PK] = $result->id; $formDatas[AccountModel::PARENT] = $this->getAuthEntity()->getPK(); @@ -45,20 +47,29 @@ class Account extends Cloudflare $formDatas['created_at'] = $result->created_on; return $formDatas; } + public function reload(): array { - log_message("notice", "-----{$this->getAuthEntity()->getTitle()} 처리 시작-----"); + log_message("notice", "\n----------Auth {$this->getAuthEntity()->getTitle()}의 Account 처리 시작-----------"); $entitys = []; - foreach ($this->reload_procedure("accounts") as $result) { - $formDatas = $this->getArrayByResult($result); - $entity = $this->getModel()->modify($this->getModel()->getEntity(), $formDatas); - $entitys[$entity->getPK()] = $entity; + try { + $account_results = $this->reload_procedure("accounts"); + if (count($account_results) > 0) { + foreach ($account_results as $result) { + $formDatas = $this->getArrayByResult($result); + $entitys[$formDatas[AccountModel::PK]] = $this->getModel()->modify(new AccountEntity(), $formDatas); + } + //부모키를 기준으로 CF에 존재하지 않는 데이터 삭제용 + $this->getModel()->where(AccountModel::PARENT, $this->getAuthEntity()->getPK()); + $this->getModel()->whereNotIn(AccountModel::PK, array_keys($entitys)); + $this->getModel()->delete(); + log_message("debug", $this->getModel()->getLastQuery()); + } + } catch (\Exception $e) { + log_message("error", $e->getMessage()); + throw new \Exception($e->getMessage()); } - //부모키를 기준으로 CF에 존재하지 않는 데이터 삭제용 - $this->getModel()->where(AccountModel::PARENT, $this->getAuthEntity()); - $this->getModel()->whereNotIn(AccountModel::PK, array_keys($entitys)); - $this->getModel()->delete(); - log_message("notice", "-----{$this->getAuthEntity()->getTitle()} 처리[" . count($entitys) . "개] 완료-----"); + log_message("notice", message: "\n-----------Auth {$this->getAuthEntity()->getTitle()}의 Account 처리[" . count($entitys) . "개] 완료-----------"); return $entitys; } } diff --git a/app/Libraries/Cloudflare/Cloudflare.php b/app/Libraries/Cloudflare/Cloudflare.php index ff7cc36..40be6c6 100644 --- a/app/Libraries/Cloudflare/Cloudflare.php +++ b/app/Libraries/Cloudflare/Cloudflare.php @@ -47,29 +47,36 @@ abstract class Cloudflare extends CommonLibrary } return $this->_accountModel; } - final protected function reload_procedure($uri): array + + private function reload_page(string $uri, int $page, int $per_page = 50): mixed + { + $query = [ + 'page' => $page, + 'per_page' => $per_page, + 'match' => 'all', + ]; + $response = $this->getMySocket()->get($uri, $query); + $cf = json_decode($response->getBody()); + if (!$cf->success) { + $message = __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true); + log_message("error", $message); + throw new \Exception($message); + } + return $cf; + } + final protected function reload_procedure(string $uri): array { $page = 1; //1부터 시작 - $results = []; - do { - $query = [ - 'page' => $page, - 'per_page' => $this->getMySocket()::$_request_perpage_max, - 'match' => 'all', - ]; - $response = $this->getMySocket()->get($uri, $query); - $cf = json_decode($response->getBody()); - if (!$cf->success) { - $message = __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true); - log_message("error", $message); - throw new \Exception($message); - } + //한번에 가져올수 있는 갯수 (countfalre 5~50사이) + $cf = $this->reload_page($uri, $page); + $per_page = $cf->result_info->per_page; + $total_page = $cf->result_info->total_pages; + $results = $cf->result; + for ($i = $page + 1; $i <= $total_page; $i++) { + $cf = $this->reload_page($uri, $i, $per_page); $results = array_merge($results, $cf->result); - if (count($cf->result) < $this->getMySocket()::$_request_perpage_max) { - break; - } - $page++; - } while (true); + log_message("debug", "현재: page[{$i}/{$total_page}] , result수[" . count($results) . "]"); + } return $results; } } diff --git a/app/Libraries/Cloudflare/Record.php b/app/Libraries/Cloudflare/Record.php index e401f4d..1522ab1 100644 --- a/app/Libraries/Cloudflare/Record.php +++ b/app/Libraries/Cloudflare/Record.php @@ -113,6 +113,7 @@ class Record extends Cloudflare //DB삭제 $this->getModel()->where(RecordModel::PK, $entity->getPK()); $this->getModel()->delete(); + log_message("debug", $this->getModel()->getLastQuery()); return $entity; } public function sync(RecordEntity $entity): RecordEntity @@ -148,18 +149,26 @@ class Record extends Cloudflare //Reload public function reload(): array { - log_message("notice", "-----{$this->_zone_entity->getTitle()} 처리 시작-----"); + log_message("notice", "\n-----------Zone {$this->_zone_entity->getTitle()}의 Record 처리 시작-----------"); $entitys = []; - foreach ($this->reload_procedure("zones/{$this->_zone_entity->getPK()}/dns_records") as $result) { - $formDatas = $this->getArrayByResult($result); - $entity = $this->getModel()->modify($this->getModel()->getEntity(), $formDatas); - $entitys[$entity->getPK()] = $entity; + try { + $record_results = $this->reload_procedure("zones/{$this->_zone_entity->getPK()}/dns_records"); + if (count($record_results) > 0) { + foreach ($record_results as $result) { + $formDatas = $this->getArrayByResult($result); + $entitys[$formDatas[RecordModel::PK]] = $this->getModel()->modify(new RecordEntity(), $formDatas); + } + //부모키를 기준으로 CF에 존재하지 않는 데이터 DB삭제 + $this->getModel()->where(RecordModel::PARENT, $this->_zone_entity->getPK()); + $this->getModel()->whereNotIn(RecordModel::PK, array_keys($entitys)); + $this->getModel()->delete(); + log_message("debug", $this->getModel()->getLastQuery()); + } + } catch (\Exception $e) { + log_message("error", $e->getMessage()); + throw new \Exception($e->getMessage()); } - //부모키를 기준으로 CF에 존재하지 않는 데이터 DB삭제 - $this->getModel()->where(RecordModel::PARENT, $this->_zone_entity); - $this->getModel()->whereNotIn(RecordModel::PK, array_keys($entitys)); - $this->getModel()->delete(); - log_message("notice", "-----{$this->_zone_entity->getTitle()} 처리[" . count($entitys) . "개] 완료-----"); + log_message("notice", "\n-----------Zone {$this->_zone_entity->getTitle()}의 Record처리[" . count($entitys) . "개] 완료-----------"); return $entitys; } } diff --git a/app/Libraries/Cloudflare/Zone.php b/app/Libraries/Cloudflare/Zone.php index 48371bd..723f95c 100644 --- a/app/Libraries/Cloudflare/Zone.php +++ b/app/Libraries/Cloudflare/Zone.php @@ -58,16 +58,15 @@ class Zone extends Cloudflare return $formDatas; } //Cfzone에서 가져온 값을 zone에 setting - private function getCFSetting(ZoneEntity $entity): array + private function getCFSetting(string $uid, array $formDatas = []): array { - $cf = $this->getMySocket()->get('zones/' . $entity->getPK() . '/settings'); + $cf = $this->getMySocket()->get('zones/' . $uid . '/settings'); $cf = json_decode($cf->getBody()); if (!$cf->success) { $message = "Zone:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true); log_message("error", $message); throw new \Exception($message); } - $formDatas = []; foreach ($cf->result as $cf) { if (in_array($cf->id, array_keys($this->_setting_fields))) { $formDatas[$cf->id] = $cf->value; @@ -75,10 +74,10 @@ class Zone extends Cloudflare } return $formDatas; } - private function setCFSetting(ZoneEntity $entity, string $field, string $value): string + private function setCFSetting(string $uid, string $field, string $value): string { $datas = ['value' => $value]; - $cf = $this->getMySocket()->patch('zones/' . $entity->getPK() . '/settings/' . $field, $datas); + $cf = $this->getMySocket()->patch('zones/' . $uid . '/settings/' . $field, $datas); $cf = json_decode($cf->getBody()); if (!$cf->success || $cf->result->id !== $field) { $message = "Zone:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true); @@ -106,21 +105,17 @@ class Zone extends Cloudflare } //DB생성 $formDatas = $this->getArrayByResult($cf->result); - $entity = $this->getModel()->create($formDatas); - - //초기화값 추가셋팅 ipv6 , development_mode , security_level - $formDatas = []; foreach ($this->_setting_fields as $field => $default) { - $formDatas[$field] = $this->setCFSetting($entity, $field, $default); + //초기화값 추가셋팅 ipv6 , development_mode , security_level + $formDatas[$field] = $this->setCFSetting($formDatas[ZoneModel::PK], $field, $default); } - //DB수정 - return $this->getModel()->modify($entity, $formDatas); + return $this->getModel()->create($formDatas); } public function modify(ZoneEntity $entity, array $formDatas): ZoneEntity { // throw new \Exception("zone:modify" . var_export($formDatas, true)); - //modify,toggle,batchjob 사용 셋팅 ipv6 , //development_mode , //security_level foreach ($formDatas as $field => $value) { + //modify,toggle,batchjob 사용 셋팅 ipv6 , //development_mode , //security_level $formDatas[$field] = $this->setCFSetting($entity, $field, $value); } //DB수정 @@ -138,6 +133,7 @@ class Zone extends Cloudflare //DB삭제 $this->getModel()->where(ZoneModel::PK, $entity->getPK()); $this->getModel()->delete(); + log_message("debug", $this->getModel()->getLastQuery()); return $entity; } public function sync(ZoneEntity $entity): ZoneEntity @@ -149,30 +145,34 @@ class Zone extends Cloudflare log_message("error", $message); throw new \Exception($message); } - $formDatas = $this->getArrayByResult($cf->result); - $entity = $this->getModel()->modify($this->getModel()->getEntity(), $formDatas); - //추가 셋팅용 - $formDatas = $this->getCFSetting($entity); + $formDatas = $this->getArrayByResult($cf->result); + $formDatas = $this->getCFSetting($formDatas[ZoneModel::PK], $formDatas); return $this->getModel()->modify($entity, $formDatas); } //Reload public function reload(): array { - log_message("notice", "-----{$this->_account_entity->getTitle()} 처리 시작-----"); + log_message("notice", "\n-----------Account {$this->_account_entity->getTitle()}의 Zone처리 시작-----------"); $entitys = []; - foreach ($this->reload_procedure('zones') as $result) { - $formDatas = $this->getArrayByResult($result); - $entity = $this->getModel()->modify($this->getModel()->getEntity(), $formDatas); - //추가 셋팅용 - $formDatas = $this->getCFSetting($entity); - $entity = $this->getModel()->modify($entity, $formDatas); - $entitys[$entity->getPK()] = $entity; + try { + $zone_results = $this->reload_procedure("zones"); + if (count($zone_results) > 0) { + foreach ($zone_results as $result) { + $formDatas = $this->getArrayByResult($result); + $formDatas = $this->getCFSetting($formDatas[ZoneModel::PK], $formDatas); + $entitys[$formDatas[ZoneModel::PK]] = $this->getModel()->modify(new ZoneEntity(), $formDatas); + } + //부모키를 기준으로 CF에 존재하지 않는 데이터 삭제용 + $this->getModel()->where(ZoneModel::PARENT, $this->_account_entity->getPK()); + $this->getModel()->whereNotIn(ZoneModel::PK, array_keys($entitys)); + $this->getModel()->delete(); + log_message("debug", $this->getModel()->getLastQuery()); + } + } catch (\Exception $e) { + log_message("error", $e->getMessage()); + throw new \Exception($e->getMessage()); } - //부모키를 기준으로 CF에 존재하지 않는 데이터 삭제용 - $this->getModel()->where(ZoneModel::PARENT, $this->_account_entity); - $this->getModel()->whereNotIn(ZoneModel::PK, array_keys($entitys)); - $this->getModel()->delete(); - log_message("notice", "-----{$this->_account_entity->getTitle()} 처리[" . count($entitys) . "개] 완료-----"); + log_message("notice", "\n----------Account {$this->_account_entity->getTitle()}의 Zone 처리[" . count($entitys) . "개] 완료-----------"); return $entitys; } } diff --git a/app/Libraries/MySocket/CloudflareSocket.php b/app/Libraries/MySocket/CloudflareSocket.php index 9c25534..7350f8f 100644 --- a/app/Libraries/MySocket/CloudflareSocket.php +++ b/app/Libraries/MySocket/CloudflareSocket.php @@ -7,9 +7,8 @@ use App\Entities\Cloudflare\AuthEntity; class CloudflareSocket extends MySocket { - private static int $_request = 0; + public static int $_request = 0; private static int $_request_max = 1000; - public static int $_request_perpage_max = 700; private static int $_request_timewait = 60; public function __construct(AuthEntity $auth_entity) { @@ -22,7 +21,7 @@ class CloudflareSocket extends MySocket ] ]); } - + //override final public function request(string $method, $uri = '', array $options = []): ResponseInterface { if (self::$_request >= self::$_request_max) { @@ -32,6 +31,7 @@ class CloudflareSocket extends MySocket log_message('warning', sprintf("--Cloudflare API Call %s초 대기 종료--", self::$_request_timewait)); } self::$_request++; + // log_message("debug", "현재 request:[" . self::$_request . "]"); return parent::request($method, $uri, $options); } } diff --git a/app/Libraries/MySocket/MySocket.php b/app/Libraries/MySocket/MySocket.php index e57dc22..53fd4b3 100644 --- a/app/Libraries/MySocket/MySocket.php +++ b/app/Libraries/MySocket/MySocket.php @@ -71,10 +71,10 @@ class MySocket extends Client { $requestOptions = $this->getRequestOptions($method, $options); $requestOptions[in_array($method, ['get', 'getAsync']) ? 'query' : 'json'] = $options; - log_message("debug", __FUNCTION__ . - "=> 호출 Socket URL:{$uri}\n--------------\n" . - var_export($options, true) . - "\n--------------\n"); + // log_message("debug", __FUNCTION__ . + // "=> 호출 Socket URL:{$uri}\n--------------\n" . + // var_export($options, true) . + // "\n--------------\n"); return parent::request($method, $uri, $requestOptions); } } diff --git a/app/Models/CommonModel.php b/app/Models/CommonModel.php index ff89093..5e8e9d1 100644 --- a/app/Models/CommonModel.php +++ b/app/Models/CommonModel.php @@ -166,7 +166,7 @@ abstract class CommonModel extends Model if (!$this->save($entity)) { throw new \Exception("저장오류:" . var_export($this->errors(), true)); } - log_message("notice", $this->getTable() . " => " . __FUNCTION__ . " DB 저장이 완료되었습니다."); + log_message("notice", $this->getTable() . " => " . __FUNCTION__ . " DB에 {$entity->getTitle()} 저장이 완료되었습니다."); return $entity; } catch (\Exception $e) { $message = sprintf( @@ -192,7 +192,7 @@ abstract class CommonModel extends Model $pkField = $this->getPKField(); $entity->$pkField = $this->getInsertID(); } - log_message("debug", $this->getTable() . " => " . __FUNCTION__ . " DB 작업 완료"); + // log_message("debug", $this->getTable() . " => " . __FUNCTION__ . " DB 작업 완료"); return $entity; } final protected function modify_process($entity, array $formDatas): mixed @@ -204,7 +204,7 @@ abstract class CommonModel extends Model $entity->$field = $this->convertEntityData($field, $formDatas); } $this->save_process($entity); - log_message("debug", $this->getTable() . " => " . __FUNCTION__ . " DB 작업 완료"); + // log_message("debug", $this->getTable() . " => " . __FUNCTION__ . " DB 작업 완료"); return $entity; }