cfmgrv4 init...1

This commit is contained in:
최준흠 2024-10-05 10:13:40 +09:00
parent fba14264be
commit b2d4d60f76
4 changed files with 84 additions and 65 deletions

View File

@ -0,0 +1,54 @@
<?php
namespace App\Libraries\MySocket\Cloudflare;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Client;
class CloudflareClient extends Client
{
const REQUEST_PERPAGE_MAX = 700;
private static int $_request = 0;
private static int $_request_max = 1000;
private static int $_request_timewait = 60;
public function __construct(array $config = [])
{
parent::__construct($config);
self::$_request_max = getenv("cfmgr.request.max") ?: 1000;
self::$_request_timewait = getenv("cfmgr.request.timewait") ?: 60;
}
public function get($uri, array $options = []): ResponseInterface
{
return $this->request('GET', $uri, $options);
}
public function post($uri, array $options = []): ResponseInterface
{
return $this->request('POST', $uri, $options);
}
public function put($uri, array $options = []): ResponseInterface
{
return $this->request('PUT', $uri, $options);
}
public function patch($uri, array $options = []): ResponseInterface
{
return $this->request('PATCH', $uri, $options);
}
public function delete($uri, array $options = []): ResponseInterface
{
return $this->request('DELETE', $uri, $options);
}
public function request(string $method, $uri = '', array $options = []): ResponseInterface
{
if (self::$_request >= self::$_request_max) {
log_message('warning', sprintf("--Cloudflare API Call %s초 대기 시작--", self::$_request_timewait));
sleep(intval(self::$_request_timewait));
self::$_request = 0;
log_message('warning', sprintf("--Cloudflare API Call %s초 대기 종료--", self::$_request_timewait));
}
self::$_request++;
$requestOptions = [];
$requestOptions[in_array($method, ['get', 'getAsync']) ? 'query' : 'json'] = $options;
return parent::request($method, $uri, $requestOptions);
}
}

View File

@ -59,7 +59,7 @@ class RecordSocket extends CloudflareSocket
'content' => $content, 'content' => $content,
'proxied' => $proxied === 'on' ? true : false 'proxied' => $proxied === 'on' ? true : false
]; ];
$cf = $this->getRequest('post', "zones/{$this->_zone_entity->getPK()}/dns_records", $datas); $cf = $this->getClient()->post("zones/{$this->_zone_entity->getPK()}/dns_records", $datas);
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success) { if (!$cf->success) {
$message = "Record:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true); $message = "Record:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true);
@ -91,7 +91,7 @@ class RecordSocket extends CloudflareSocket
} }
// 인코딩된 JSON을 확인 // 인코딩된 JSON을 확인
// throw new \Exception("Record:" . __FUNCTION__ . "\n" . json_encode($datas, JSON_PRETTY_PRINT) . "\n" . var_export($datas, true)); // throw new \Exception("Record:" . __FUNCTION__ . "\n" . json_encode($datas, JSON_PRETTY_PRINT) . "\n" . var_export($datas, true));
$cf = $this->getRequest('put', "zones/{$this->_zone_entity->getPK()}/dns_records/{$entity->getPK()}", $datas); $cf = $this->getClient()->put("zones/{$this->_zone_entity->getPK()}/dns_records/{$entity->getPK()}", $datas);
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success) { if (!$cf->success) {
$message = "Record:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true); $message = "Record:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true);
@ -104,7 +104,7 @@ class RecordSocket extends CloudflareSocket
} }
public function delete(RecordEntity $entity): void public function delete(RecordEntity $entity): void
{ {
$cf = $this->getRequest('delete', "zones/{$this->_zone_entity->getPK()}/dns_records/{$entity->getPK()}"); $cf = $this->getClient()->delete("zones/{$this->_zone_entity->getPK()}/dns_records/{$entity->getPK()}");
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success) { if (!$cf->success) {
$message = "Record:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true); $message = "Record:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true);
@ -118,7 +118,7 @@ class RecordSocket extends CloudflareSocket
public function sync(RecordEntity $entity): void public function sync(RecordEntity $entity): void
{ {
// 기존 Sync형태 // 기존 Sync형태
$cf = $this->getRequest('get', "zones/{$this->_zone_entity->getPK()}/dns_records/{$entity->getPK()}"); $cf = $this->getClient()->get("zones/{$this->_zone_entity->getPK()}/dns_records/{$entity->getPK()}");
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success) { if (!$cf->success) {
$message = "Record:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true); $message = "Record:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true);
@ -129,7 +129,7 @@ class RecordSocket extends CloudflareSocket
log_message("debug", var_export($cf->result, true)); log_message("debug", var_export($cf->result, true));
$entity = $this->getModel()->modify($entity, $this->getArrayByResult($cf->result)); $entity = $this->getModel()->modify($entity, $this->getArrayByResult($cf->result));
//Async형태 //Async형태
// $promise = $this->getRequest('getAsync', "zones/{$this->_zone_entity->getPK()}/dns_records/{$entity->getPK()}"); // $promise = $this->getClient()->getAsync("zones/{$this->_zone_entity->getPK()}/dns_records/{$entity->getPK()}");
// $promise->then( // $promise->then(
// onFulfilled: function ($response) use ($entity): RecordEntity { // onFulfilled: function ($response) use ($entity): RecordEntity {
// $record = json_decode($response->getBody(), true)['result']; // $record = json_decode($response->getBody(), true)['result'];

View File

@ -60,7 +60,7 @@ class ZoneSocket extends CloudflareSocket
//Cfzone에서 가져온 값을 zone에 setting //Cfzone에서 가져온 값을 zone에 setting
private function getCFSetting(ZoneEntity $entity): array private function getCFSetting(ZoneEntity $entity): array
{ {
$cf = $this->getRequest('get', 'zones/' . $entity->getPK() . '/settings'); $cf = $this->getClient()->get('zones/' . $entity->getPK() . '/settings');
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success) { if (!$cf->success) {
$message = "Zone:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true); $message = "Zone:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true);
@ -78,7 +78,7 @@ class ZoneSocket extends CloudflareSocket
private function setCFSetting(ZoneEntity $entity, string $field, string $value): string private function setCFSetting(ZoneEntity $entity, string $field, string $value): string
{ {
$datas = ['value' => $value]; $datas = ['value' => $value];
$cf = $this->getRequest('patch', 'zones/' . $entity->getPK() . '/settings/' . $field, $datas); $cf = $this->getClient()->patch('zones/' . $entity->getPK() . '/settings/' . $field, $datas);
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success || $cf->result->id !== $field) { if (!$cf->success || $cf->result->id !== $field) {
$message = "Zone:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true); $message = "Zone:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true);
@ -97,7 +97,7 @@ class ZoneSocket extends CloudflareSocket
'name' => $domain, 'name' => $domain,
'jump_start' => $jump_start, 'jump_start' => $jump_start,
]; ];
$cf = $this->getRequest('post', 'zones/', $datas); $cf = $this->getClient()->post('zones/', $datas);
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success) { if (!$cf->success) {
$message = "Zone:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true); $message = "Zone:" . __FUNCTION__ . "에서 실패:\nrequest:" . var_export($datas, true) . "\nresponse:" . var_export($cf, true);
@ -128,7 +128,7 @@ class ZoneSocket extends CloudflareSocket
} }
public function delete(ZoneEntity $entity): void public function delete(ZoneEntity $entity): void
{ {
$cf = $this->getRequest('delete', "zones/{$entity->getPK()}"); $cf = $this->getClient()->delete("zones/{$entity->getPK()}");
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success) { if (!$cf->success) {
$message = "Zone:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true); $message = "Zone:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true);
@ -141,7 +141,7 @@ class ZoneSocket extends CloudflareSocket
} }
public function sync(ZoneEntity $entity): void public function sync(ZoneEntity $entity): void
{ {
$cf = $this->getRequest('get', "zones/{$entity->getPK()}"); $cf = $this->getClient()->get("zones/{$entity->getPK()}");
$cf = json_decode($cf->getBody()); $cf = json_decode($cf->getBody());
if (!$cf->success) { if (!$cf->success) {
$message = "Zone:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true); $message = "Zone:" . __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true);

View File

@ -2,22 +2,14 @@
namespace App\Libraries\MySocket; namespace App\Libraries\MySocket;
use App\Entities\Cloudflare\AuthEntity;
use App\Libraries\CommonLibrary; use App\Libraries\CommonLibrary;
use App\Models\Cloudflare\AccountModel; use App\Libraries\MySocket\Cloudflare\CloudflareClient;
use App\Models\Cloudflare\AuthModel; use App\Models\Cloudflare\AuthModel;
use Cloudflare\API\Adapter\ResponseException; use App\Models\Cloudflare\AccountModel;
use GuzzleHttp\Client; use App\Entities\Cloudflare\AuthEntity;
use GuzzleHttp\Exception\RequestException;
abstract class CloudflareSocket extends CommonLibrary abstract class CloudflareSocket extends CommonLibrary
{ {
private static int $_request = 0;
private static int $_request_max = 1000;
private static int $_request_perpage_max = 700;
private static int $_request_timewait = 60;
private $_authModel = null; private $_authModel = null;
private $_accountModel = null; private $_accountModel = null;
private $_client = null; private $_client = null;
@ -26,16 +18,13 @@ abstract class CloudflareSocket extends CommonLibrary
{ {
parent::__construct(); parent::__construct();
$this->_auth_entity = $auth_entity; $this->_auth_entity = $auth_entity;
self::$_request_max = getenv("cfmgr.request.max") ?: 1000;
self::$_request_perpage_max = getenv("cfmgr.request.perpage.max") ?: 700;
self::$_request_timewait = getenv("cfmgr.request.timewait") ?: 60;
} }
abstract protected function getArrayByResult($result, array $formDatas = []): array; abstract protected function getArrayByResult($result, array $formDatas = []): array;
private function getClient(): Client final protected function getClient(): CloudflareClient
{ {
if ($this->_client === null) { if ($this->_client === null) {
// Guzzle HTTP 클라이언트를 설정하면서 Cloudflare API 토큰 사용 // Guzzle HTTP 클라이언트를 설정하면서 Cloudflare API 토큰 사용
$this->_client = new Client([ $this->_client = new CloudflareClient([
'base_uri' => 'https://api.cloudflare.com/client/v4/', 'base_uri' => 'https://api.cloudflare.com/client/v4/',
'headers' => [ 'headers' => [
'X-Auth-Email' => $this->_auth_entity->getID(), // 인증 토큰 사용 'X-Auth-Email' => $this->_auth_entity->getID(), // 인증 토큰 사용
@ -61,53 +50,29 @@ abstract class CloudflareSocket extends CommonLibrary
} }
return $this->_accountModel; return $this->_accountModel;
} }
final protected function getRequest(string $method, string $uri, array $datas = [])
{
if (!in_array($method, ['get', 'getAsync', 'post', 'put', 'patch', 'delete'])) {
throw new \InvalidArgumentException('Request method must be get, post, put, patch, or delete');
}
try {
$response = $this->getClient()->$method($uri, [
in_array($method, ['get', 'getAsync']) ? 'query' : 'json' => $datas,
]);
if (self::$_request >= self::$_request_max) {
log_message('warning', sprintf("--Cloudflare API Call %s초 대기 시작--", self::$_request_timewait));
sleep(intval(self::$_request_timewait));
self::$_request = 0;
log_message('warning', sprintf("--Cloudflare API Call %s초 대기 종료--", self::$_request_timewait));
}
self::$_request++;
} catch (RequestException $err) {
throw ResponseException::fromRequestException($err);
}
return $response;
}
final protected function reload_procedure($uri): array final protected function reload_procedure($uri): array
{ {
$page = 1; //Page는 1부터 시작해야함 $page = 1; //1부터 시작
$perpage_max = self::$_request_perpage_max; $results = [];
$results = [];
do { do {
$query = [ $query = [
'page' => $page, 'page' => $page,
'per_page' => $perpage_max, 'per_page' => CloudflareClient::REQUEST_PERPAGE_MAX,
'match' => 'all', 'match' => 'all',
]; ];
$cf = $this->getClient()->get($uri, $query); $response = $this->getClient()->get($uri, $query);
$cf = json_decode($cf->getBody()); $cf = json_decode($response->getBody());
if (!$cf->success) { if (!$cf->success) {
throw new \Exception(__FUNCTION__ . "에서 실패:\n" . var_export($cf, true)); $message = __FUNCTION__ . "에서 실패:\nresponse:" . var_export($cf, true);
log_message("error", $message);
throw new \Exception($message);
} }
//Loop 제한 : 한페이지에서 가져온 갯수가 perpage_max보다 적다는것은 더이상 다음페이지기 없으므로 0로 종료시키기 위함 $results = array_merge($results, $cf->result);
if (count($cf->result) < $perpage_max) { if (count($cf->result) < CloudflareClient::REQUEST_PERPAGE_MAX) {
$results = $cf->result; break;
$page = 0;
} else {
$results = array_merge($results, $cf->result);
$page++;
} }
} while (0 < $page); $page++;
} while (true);
return $results; return $results;
} }
} }