Files
portal-api/app/Services/ServerService.php
T

342 lines
11 KiB
PHP

<?php
namespace App\Services;
use App\Facades\BaseHelperFacade as BaseHelper;
use App\Models\DnsServer;
use App\Repositories\DnsManager\Server\DnsServerRepositoryInterface;
use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class ServerService
{
protected $server;
protected array $payload = [
'host' => '',
'type' => 'A',
'value' => '',
'opt' => '',
'ttl' => 300,
];
protected string $domain = '';
protected array $entry_points = [
'auth' => ':8443/api/v2/auth/keys',
'server' => ':8443/api/v2/server',
'domain' => ':8443/api/v2/domains',
'record' => ':8443/api/v2/dns/records',
];
public function __construct(
public DnsServerRepositoryInterface $serverRepository
) {
$this->server = $this->getServer();
}
public function findServerByID(int $id): ?DnsServer
{
return $this->server = $this->serverRepository->find($id);
}
public function handlePayload(array $data = []): static
{
$this->domain = $data['domain'] ?? '';
$name = $data['name'] ?? '';
$this->payload = [
'type' => $data['type'] ?? 'A',
'host' => $name === '@' ? $this->domain : ($name . '.' . $this->domain),
'value' => str_replace(["\r", "\n"], ' ', $data['value'] ?? ''),
'ttl' => $data['ttl'] ?? 300,
];
switch (strtoupper($this->payload['type'])) {
case 'MX':
$this->payload['opt'] = $data['priority'] ?? 0;
break;
case 'SRV':
$this->payload['host'] = sprintf('_%s._%s.%s', $data['service_name'], $data['protocol'], $this->domain);
$this->payload['opt'] = sprintf('%d %d %d', $data['priority'] ?? 0, $data['weight'] ?? 50, $data['port'] ?? 21);
break;
}
return $this;
}
public function addRecord(): array
{
if (empty($this->domain)) {
return ['error' => true, 'message' => 'Invalid domain'];
}
try {
$response = Http::withoutVerifying()
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
->timeout(10)
->post(
BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . '?' . http_build_query(['domain' => $this->domain]),
$this->payload
)->throw();
$this->resetServer();
return $response->successful() && count($response->json())
? ['error' => false, 'data' => $response->json()]
: ['error' => true];
} catch (RequestException $e) {
Log::error($e->getMessage());
return ['error' => true, 'message' => $e->getMessage()];
}
}
public function updateRecord(int $record_id = 0): array
{
if (empty($record_id)) {
return ['error' => true, 'message' => 'Invalid request'];
}
try {
$response = Http::withoutVerifying()
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
->timeout(10)
->put(
BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . "/$record_id",
$this->payload
)->throw();
$this->resetServer();
return $response->successful() && count($response->json())
? ['error' => false, 'data' => $response->json()]
: ['error' => true];
} catch (RequestException $e) {
Log::error($e->getMessage());
return ['error' => true, 'message' => $e->getMessage()];
}
}
public function deleteRecord(int $record_id = 0): array
{
if (empty($record_id)) {
return ['error' => true, 'message' => 'Invalid request'];
}
try {
$response = Http::withoutVerifying()
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
->timeout(30)
->delete(
BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . "/$record_id"
)->throw();
$this->resetServer();
return $response->successful() && count($response->json())
? ['error' => false, 'data' => $response->json()]
: ['error' => true];
} catch (RequestException $e) {
Log::error($e->getMessage());
return ['error' => true, 'message' => $e->getMessage()];
}
}
public function checkConnection(array $data = []): bool
{
if (empty($data['username']) || empty($data['password']) || empty($data['ip_address'])) {
return false;
}
try {
$response = Http::withoutVerifying()
->withBasicAuth($data['username'], $data['password'])
->timeout(10)
->get(BaseHelper::url($data['ip_address']) . $this->entry_points['server']);
return $response->successful();
} catch (RequestException $e) {
Log::error($e->getMessage());
return false;
}
}
public function getDomainInfo(string $domain = ''): array|false
{
if (empty($domain)) {
return false;
}
try {
$response = Http::withoutVerifying()
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
->timeout(10)
->get(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'], ['name' => $domain]);
$this->resetServer();
if ($response->successful()) {
$domains = $response->json();
foreach ($domains as $domainInfo) {
if (isset($domainInfo['name']) && $domainInfo['name'] === $domain) {
return $domainInfo;
}
}
}
return false;
} catch (RequestException $e) {
Log::error($e->getMessage());
return false;
}
}
public function createDomain(array $data = []): array|false
{
if (empty($data)) {
return false;
}
if (!$this->server) {
$this->server = $this->serverRepository->find($data['dns_manager_server_id']);
}
$param = [
'name' => $data['domain_name'],
'description' => '',
'hosting_type' => 'virtual',
'hosting_settings' => [
'ftp_login' => str_replace('.', '_', $data['domain_name']),
'ftp_password' => Str::random(12),
],
'ip_addresses' => ['103.42.58.124'],
'ipv4' => ['103.42.58.124'],
'plan' => ['name' => 'Default Domain'],
];
try {
$response = Http::withoutVerifying()
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
->timeout(30)
->post(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'], $param);
$this->resetServer();
$responseData = $response->json();
Log::info('Response Plesk API Created', ['data' => $responseData]);
if ($response->successful() && isset($responseData['id'], $responseData['guid'])) {
return $responseData;
}
} catch (RequestException $e) {
Log::error('Plesk domain creation failed', [
'error' => $e->getMessage(),
'response' => $e->response?->body(),
'data' => $param,
]);
}
return false;
}
public function updateDomain(int $pleskDomainId, array $data = []): array|false
{
if (empty($pleskDomainId) || empty($data)) {
return false;
}
if (!$this->server) {
$this->server = $this->serverRepository->find($data['dns_manager_server_id']);
}
$param = [
'name' => $data['domain_name'],
'description' => '',
'hosting_type' => 'virtual',
'hosting_settings' => [
'ftp_login' => str_replace('.', '_', $data['domain_name']),
'ftp_password' => Str::random(12),
],
'ip_addresses' => ['103.42.58.124'],
'ipv4' => ['103.42.58.124'],
'plan' => ['name' => 'Default Domain'],
];
try {
$response = Http::withoutVerifying()
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
->timeout(30)
->put(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'] . "/{$pleskDomainId}", $param);
$this->resetServer();
$responseData = $response->json();
Log::info('Response Plesk API Updated', ['data' => $responseData]);
if ($response->successful() && isset($responseData['id'], $responseData['guid'])) {
return $responseData;
}
} catch (RequestException $e) {
Log::error('Plesk domain update failed', [
'error' => $e->getMessage(),
'response' => $e->response?->body(),
'data' => $param,
]);
}
return false;
}
public function removeDomain(int $pleskDomainId): bool
{
if (empty($this->server)) {
return false;
}
try {
$response = Http::withoutVerifying()
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
->timeout(30)
->delete(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'] . "/{$pleskDomainId}");
$this->resetServer();
if ($response->successful()) {
Log::info('Xoá domain thành công', ['plesk_id' => $pleskDomainId, 'status' => $response->status()]);
return true;
}
Log::error('Xoá domain thất bại', [
'plesk_id' => $pleskDomainId,
'status' => $response->status(),
'response' => $response->body(),
]);
return false;
} catch (\Exception $e) {
Log::error('Exception khi xoá domain', ['plesk_id' => $pleskDomainId, 'error' => $e->getMessage()]);
return false;
}
}
public function addServerById(int $serverId): bool
{
$this->server = $this->serverRepository->find($serverId);
return !empty($this->server);
}
private function getServer(): ?DnsServer
{
return $this->serverRepository->getActived()->first();
}
private function resetServer(): void
{
$this->server = null;
}
}