cfmgrv4 init...1

This commit is contained in:
최준흠 2024-10-05 11:51:52 +09:00
parent 56a742904a
commit d40f836dc6
7 changed files with 145 additions and 172 deletions

View File

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

View File

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

View File

@ -2,39 +2,47 @@
namespace App\Libraries\MySocket;
use App\Libraries\CommonLibrary;
use App\Libraries\MySocket\Cloudflare\CloudflareClient;
use Psr\Http\Message\ResponseInterface;
use App\Models\Cloudflare\AuthModel;
use App\Models\Cloudflare\AccountModel;
use App\Entities\Cloudflare\AuthEntity;
abstract class CloudflareSocket extends CommonLibrary
abstract class CloudflareSocket extends MySocket
{
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 $_accountModel = null;
private $_client = null;
private $_auth_entity = null;
protected function __construct(AuthEntity $auth_entity)
{
parent::__construct();
$this->_auth_entity = $auth_entity;
}
abstract protected function getArrayByResult($result, array $formDatas = []): array;
final protected function getClient(): CloudflareClient
{
if ($this->_client === null) {
// Guzzle HTTP 클라이언트를 설정하면서 Cloudflare API 토큰 사용
$this->_client = new CloudflareClient([
parent::__construct([
'base_uri' => 'https://api.cloudflare.com/client/v4/',
'headers' => [
'X-Auth-Email' => $this->_auth_entity->getID(), // 인증 토큰 사용
'X-Auth-Key' => $this->_auth_entity->getAuthKey(), // 인증 토큰 사용
'Content-Type' => 'application/json',
],
'verify' => getenv("socket.web.ssl.verify") == "true" ? true : false, // SSL 인증서 검증을 비활성화
]
]);
$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;
}
return $this->_client;
abstract protected function getArrayByResult($result, array $formDatas = []): array;
final 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++;
return parent::request($method, $uri, $options);
}
final protected function getAuthModel(): AuthModel
{
@ -57,7 +65,7 @@ abstract class CloudflareSocket extends CommonLibrary
do {
$query = [
'page' => $page,
'per_page' => CloudflareClient::REQUEST_PERPAGE_MAX,
'per_page' => self::$_request_perpage_max,
'match' => 'all',
];
$response = $this->getClient()->get($uri, $query);
@ -68,7 +76,7 @@ abstract class CloudflareSocket extends CommonLibrary
throw new \Exception($message);
}
$results = array_merge($results, $cf->result);
if (count($cf->result) < CloudflareClient::REQUEST_PERPAGE_MAX) {
if (count($cf->result) < self::$_request_perpage_max) {
break;
}
$page++;

View File

@ -2,31 +2,21 @@
namespace App\Libraries\MySocket;
use App\Libraries\CommonLibrary;
use GuzzleHttp\Client;
class GoogleSocket extends CommonLibrary
class GoogleSocket extends Google_Client
{
private $_client = null;
private $_session = null;
private $_access_code = "";
public function __construct()
{
parent::__construct();
$this->_session = \Config\Services::session();
}
//Override
public function getClient(): Google_Client
{
if (is_null($this->_client)) {
$this->_client = new Google_Client();
$this->_client->setClientId(getenv("socket.google.client.id"));
$this->_client->setClientSecret(getenv("socket.google.client.key"));
$this->_client->setRedirectUri(base_url() . getenv("socket.google.client.callback_url"));
$this->_client->addScope('email');
$this->_client->addScope('profile');
}
return $this->_client;
$this->setClientId(getenv("socket.google.client.id"));
$this->setClientSecret(getenv("socket.google.client.key"));
$this->setRedirectUri(base_url() . getenv("socket.google.client.callback_url"));
$this->addScope('email');
$this->addScope('profile');
}
public function getAccessCode(): string
@ -44,13 +34,13 @@ class GoogleSocket extends CommonLibrary
public function setAccessToken()
{
//2.토큰정보 가져오기
$tokenInfo = $this->getClient()->fetchAccessTokenWithAuthCode($this->getAccessCode());
$tokenInfo = $this->fetchAccessTokenWithAuthCode($this->getAccessCode());
if (isset($tokenInfo['error'])) {
throw new \Exception($tokenInfo['error']);
}
$token = $tokenInfo[getenv("socket.google.client.token_name")];
//3. Google Service에 접근하기위해 Access Token을 설정
$this->getClient()->setAccessToken($token);
$this->setAccessToken($token);
//4. Google에 로그인이 했으므로 세션에 Token값 설정
$this->_session->set(getenv("socket.google.client.token_name"), $token);
}

View File

@ -0,0 +1,80 @@
<?php
namespace App\Libraries\MySocket;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Client;
abstract class MySocket extends Client
{
private $_cookieJar = null;
protected function __construct(array $config = [])
{
// SSL 인증서 검증을 비활성화
$config['verify'] = getenv("socket.web.ssl.verify") == "true" ? true : false;
parent::__construct($config);
}
final protected function getCookieJar(): CookieJar
{
if ($this->_cookieJar === null) {
$this->_cookieJar = new CookieJar();
}
return $this->_cookieJar;
}
protected function getUserAgent(): string
{
// User-Agent 목록 배열
$userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
'Mozilla/5.0 (Linux; Android 10; SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Mobile Safari/537.36'
];
return $userAgents[array_rand($userAgents)];
}
protected function getRequestOptions(string $method, array $options = []): array
{
//cookies->쿠키값 , timeout->5초 안에 응답이 없으면 타임아웃
$requestOptions = [
'cookies' => $this->getCookieJar(),
'timeout' => getenv("socket.web.timeout"),
'headers' => [
'User-Agent' => $this->getUserAgent(),
],
];
return $requestOptions;
}
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
{
$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");
return parent::request($method, $uri, $requestOptions);
}
}

View File

@ -2,89 +2,38 @@
namespace App\Libraries\MySocket;
use App\Libraries\CommonLibrary;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;
class WebSocket extends CommonLibrary
class WebSocket extends MySocket
{
private $_host = null;
private $_client = null;
private $_cookieJar = null;
public function __construct(string $host)
{
parent::__construct();
$this->_host = $host;
}
final public function getHost(): string
final public function getURL($uri): string
{
return $this->_host;
// url에 http 나 https가 포함되어 있지않으면
if (!preg_match('~^(http|https)://~i', $uri)) {
$uri = "{$this->_host}{$uri}";
}
final public function getClient(): Client
return $uri;
}
public function getResponse($uri, array $options = []): ResponseInterface
{
if ($this->_client === null) {
$this->_client = new Client(['verify' => getenv("socket.web.ssl.verify") == "true" ? true : false]);
$response = parent::get($this->getURL($uri), $options);
if ($response->getStatusCode() != 200) {
throw new \Exception("error", __FUNCTION__ .
"=> {$uri} 접속실패: " .
$response->getStatusCode());
}
return $this->_client;
return $response;
}
final protected function getCookieJar()
public function getContent(string $uri, array $options = []): string
{
if ($this->_cookieJar === null) {
$this->_cookieJar = new CookieJar();
}
return $this->_cookieJar;
}
//url에 http 나 https가 포함되어 있으면 true
final public function isContainsHttpOrHttps($url): bool
{
return strpos($url, 'http://') !== false || strpos($url, 'https://') !== false;
}
public function getResponseOptions(string $type, array $options = []): array
{
switch ($type) {
case 'agent':
// User-Agent 목록 배열
$userAgents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Safari/605.1.15',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
'Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
'Mozilla/5.0 (Linux; Android 10; SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Mobile Safari/537.36'
];
// 배열에서 랜덤으로 하나의 User-Agent 선택
$randomUserAgent = $userAgents[array_rand($userAgents)];
$options['headers'] = [
'User-Agent' => $randomUserAgent,
];
break;
}
return $options;
}
public function getResponse(string $url, $method = "get", array $options = []): mixed
{
//url에 http 나 https가 포함되어 있지않으면
if (!($this->isContainsHttpOrHttps($url))) {
$url = $this->gethost() . $url;
}
//기본 Option
$options['cookies'] = $this->getCookieJar(); //쿠키값
$options['timeout'] = getenv("socket.web.timeout"); // 5초 안에 응답이 없으면 타임아웃
log_message("debug", __FUNCTION__ . "=> 호출 Socket URL-> " . $url);
return $this->getClient()->$method($url, $options);
}
public function getContent(string $url, $method = "get", array $options = []): string
{
log_message("debug", __FUNCTION__ . "=> 호출 URL:" . $url);
$response = $this->getResponse($url, $method, $options);
if ($response->getStatusCode() == 200) {
$response = $this->getResponse($uri, $options);
// return $response->getBody()->getContents();
return $response->getBody();
}
throw new \Exception("error", __FUNCTION__ . "=> {$url} 접속실패: " . $response->getStatusCode());
}
}