Files
portal-api/app/Services/ServerService.php
2026-09-28 08:26:29 +07:00

253 lines
7.9 KiB
PHP

<?php
namespace App\Services;
use App\Facades\BaseHelperFacade as BaseHelper;
use App\Models\DnsServer;
use App\Repositories\DnsManager\Server\DnsServerRepositoryInterface;
use App\Services\Plesk\PleskDomainService;
use App\Support\TlsHttpClientFactory;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
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,
private PleskDomainService $pleskDomainService,
) {
$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 = TlsHttpClientFactory::plesk()
->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 listRecords(string $domain): array
{
if (empty($domain)) {
return ['error' => true, 'message' => 'Invalid domain'];
}
try {
$response = TlsHttpClientFactory::plesk()
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
->timeout(15)
->get(
BaseHelper::url($this->server->ip_address) . $this->entry_points['record'],
['domain' => $domain]
)->throw();
$this->resetServer();
return ['error' => false, 'data' => $response->json() ?? []];
} 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 = TlsHttpClientFactory::plesk()
->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 = TlsHttpClientFactory::plesk()
->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 = []): array|false
{
if (empty($data['username']) || empty($data['password']) || empty($data['ip_address'])) {
return false;
}
try {
$response = TlsHttpClientFactory::plesk()
->withBasicAuth($data['username'], $data['password'])
->timeout(10)
->get(BaseHelper::url($data['ip_address']) . $this->entry_points['server']);
return $response->successful() ? $response->json() : false;
} catch (RequestException $e) {
Log::error($e->getMessage());
return false;
}
}
public function checkConnectionByServer(DnsServer $server): array|false
{
try {
return $this->checkConnection([
'username' => $server->username,
'password' => Crypt::decryptString($server->password),
'ip_address' => $server->ip_address,
]);
} catch (\Throwable $e) {
Log::error($e->getMessage());
return false;
}
}
public function getDomainInfo(string $domain = ''): array|false
{
if (empty($domain) || empty($this->server)) {
return false;
}
$result = $this->pleskDomainService->getDomainInfo($this->server, $domain);
$this->resetServer();
return $result;
}
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']);
}
$result = $this->pleskDomainService->createDomain($this->server, $data);
$this->resetServer();
return $result;
}
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;
}
}