Files
portal-api/app/Services/VirtualMachine/VmInfrastructureResolver.php
T

90 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\VirtualMachine;
use App\Models\ModuleHost;
use App\Models\OrderItem;
use App\Models\Os;
use App\Services\VirtualMachine\Dto\VmInfrastructureContext;
use RuntimeException;
class VmInfrastructureResolver
{
public function __construct(private readonly VmProvisionLogger $logger)
{
}
public function resolve(OrderItem $item, $product): VmInfrastructureContext
{
$os = Os::with(['host.datacenter.vCenter', 'osGroup.host.datacenter.vCenter'])
->find($item->os_id);
if (!$os) {
throw new RuntimeException(
"Không tìm thấy OS id={$item->os_id} trong OrderItem #{$item->id}. os_id không hợp lệ."
);
}
// Priority 1: host attached directly to OS
$host = $os->host;
$datacenter = $host?->datacenter;
$vcenter = $datacenter?->vCenter;
// Priority 2: host from OS group fallback
if (!$host || !$datacenter || !$vcenter) {
$groupHost = $os->osGroup?->host;
$host = $host ?? $groupHost;
$datacenter = $datacenter ?? $groupHost?->datacenter;
$vcenter = $vcenter ?? $groupHost?->datacenter?->vCenter;
if ($groupHost) {
$this->logger->step('Infrastructure fallback: osGroup host', [
'os_id' => $os->id,
'os_group_id' => $os->os_group_id,
'host_id' => $groupHost->id,
]);
}
}
// Priority 3: host from product (Provisioning tab)
if ((!$host || !$datacenter || !$vcenter) && $product && $product->module_host_id) {
$productHost = ModuleHost::with('datacenter.vCenter')->find($product->module_host_id);
if ($productHost) {
$host = $host ?? $productHost;
$datacenter = $datacenter ?? $productHost->datacenter;
$vcenter = $vcenter ?? $productHost->datacenter?->vCenter;
$this->logger->step('Infrastructure fallback: product host', [
'product_id' => $product->id,
'host_id' => $productHost->id,
'datacenter_id' => $productHost->datacenter?->id,
]);
}
}
if (!$vcenter || !$host || !$datacenter) {
throw new RuntimeException(
"Thiếu thông tin host/datacenter/vcenter từ sản phẩm ID #" . ($product->id ?? 'unknown') . ". "
. "Vui lòng cấu hình vCenter trong tab Provisioning của sản phẩm, "
. "hoặc gán host cho OS group của OS được chọn."
);
}
$osGroupName = $os->osGroup?->name ?? '';
$isWindows = str_contains(strtolower($osGroupName), 'windows');
return new VmInfrastructureContext(
os: $os,
host: $host,
datacenter: $datacenter,
vcenter: $vcenter,
template: $os->template_id,
isWindows: $isWindows,
vmUser: $isWindows ? 'administrator' : 'root',
vmPort: $isWindows ? 3389 : 22,
);
}
}