109 lines
3.6 KiB
PHP
109 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs\DnsManager;
|
|
|
|
use App\Events\DnsSyncCompleted;
|
|
use App\Repositories\DnsManager\Domain\DnsDomainRepositoryInterface;
|
|
use App\Repositories\DnsManager\Record\DnsRecordRepositoryInterface;
|
|
use App\Services\ServerService;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
use Illuminate\Queue\InteractsWithQueue;
|
|
use Illuminate\Queue\SerializesModels;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class SyncDnsFromPlesk implements ShouldQueue
|
|
{
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
|
private const PLESK_RECORD_TYPES = ['A', 'AAAA', 'CNAME', 'TXT', 'MX', 'NS', 'SRV'];
|
|
|
|
public function handle(
|
|
DnsDomainRepositoryInterface $domainRepository,
|
|
DnsRecordRepositoryInterface $recordRepository,
|
|
ServerService $serverService,
|
|
): void {
|
|
$domains = $domainRepository->model
|
|
->whereNotNull('dns_manager_server_id')
|
|
->get();
|
|
|
|
$synced = 0;
|
|
$failedDomains = [];
|
|
|
|
foreach ($domains as $domain) {
|
|
if (!$serverService->addServerById($domain->dns_manager_server_id)) {
|
|
$failedDomains[] = $domain->domain_name;
|
|
continue;
|
|
}
|
|
|
|
$result = $serverService->listRecords($domain->domain_name);
|
|
|
|
if ($result['error']) {
|
|
$failedDomains[] = $domain->domain_name;
|
|
continue;
|
|
}
|
|
|
|
foreach ($result['data'] as $item) {
|
|
$type = strtoupper($item['type'] ?? '');
|
|
if (!in_array($type, self::PLESK_RECORD_TYPES, true) || empty($item['id'])) {
|
|
continue;
|
|
}
|
|
|
|
$recordRepository->model->updateOrCreate(
|
|
[
|
|
'dns_manager_domain_id' => $domain->id,
|
|
'plesk_id' => $item['id'],
|
|
],
|
|
$this->mapPleskRecord($item, $type, $domain->domain_name)
|
|
);
|
|
|
|
$synced++;
|
|
}
|
|
}
|
|
|
|
Log::info('DNS sync from Plesk finished', ['synced' => $synced, 'failed_domains' => $failedDomains]);
|
|
|
|
event(new DnsSyncCompleted($synced, $failedDomains));
|
|
}
|
|
|
|
private function mapPleskRecord(array $item, string $type, string $domainName): array
|
|
{
|
|
$host = rtrim($item['host'] ?? '', '.');
|
|
$domainName = rtrim($domainName, '.');
|
|
$name = $host === $domainName
|
|
? '@'
|
|
: preg_replace('/\.' . preg_quote($domainName, '/') . '$/', '', $host);
|
|
|
|
$opt = trim((string) ($item['opt'] ?? ''));
|
|
$priority = null;
|
|
$weight = null;
|
|
$port = null;
|
|
$serviceName = null;
|
|
$protocol = null;
|
|
|
|
if ($type === 'SRV') {
|
|
[$priority, $weight, $port] = array_pad(preg_split('/\s+/', $opt), 3, null);
|
|
if (preg_match('/^_([^.]+)\._([^.]+)\./', $name, $m)) {
|
|
$serviceName = '_' . $m[1];
|
|
$protocol = '_' . $m[2];
|
|
}
|
|
} elseif ($type === 'MX') {
|
|
$priority = is_numeric($opt) ? $opt : null;
|
|
}
|
|
|
|
return [
|
|
'type' => $type,
|
|
'type_valid' => $type,
|
|
'name' => $name,
|
|
'value' => $item['value'] ?? '',
|
|
'ttl' => $item['ttl'] ?? 300,
|
|
'priority' => $priority,
|
|
'weight' => $weight,
|
|
'port' => $port,
|
|
'service_name' => $serviceName,
|
|
'protocol' => $protocol,
|
|
];
|
|
}
|
|
}
|