update show ip & reinstall vps 50%

This commit is contained in:
Pham Bao
2025-08-04 00:35:54 +07:00
parent 160b7cdb47
commit fc277e5ef6
7 changed files with 683 additions and 93 deletions
@@ -11,11 +11,13 @@ use App\Http\Services\vCenter;
use App\Models\ModuleSnapshot;
use App\Models\ModuleVmware;
use App\Models\Order;
use App\Models\Os;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Validator as ValidatorInstance;
class ServiceController extends Controller
{
@@ -146,8 +148,11 @@ class ServiceController extends Controller
// Lấy thông tin IP
$ipAddress = 'N/A';
if ($ipInfo['error'] === false && !empty($ipInfo['data']['ip_addresses'])) {
$ipAddress = $ipInfo['data']['ip_addresses'][0] ?? 'N/A';
if ($ipInfo['error'] === false && !empty($ipInfo['data']['ip_address'])) {
$ipAddress = $ipInfo['data']['ip_address'] ?? 'N/A';
} elseif ($ipInfo['error'] === false && isset($ipInfo['data']['value']['ip_address'])) {
// Fallback for nested structure
$ipAddress = $ipInfo['data']['value']['ip_address'] ?? 'N/A';
}
// Tính toán thông tin phần cứng
@@ -414,7 +419,6 @@ class ServiceController extends Controller
->onQueue('snapshots');
return redirect()->back()->with('success', 'Đã gửi yêu cầu tạo snapshot. Quá trình sẽ mất 3-5 phút, vui lòng chờ đợi.');
} catch (\Exception $e) {
Log::error('❌ Lỗi khi tạo snapshot', [
'product_id' => $request->product_id ?? 'not_provided',
@@ -527,7 +531,6 @@ class ServiceController extends Controller
'data' => $responseData,
'cached' => false
]);
} catch (\Exception $e) {
Log::error('Lỗi khi lấy danh sách snapshot', [
'user_id' => $user->id ?? 'guest',
@@ -618,7 +621,6 @@ class ServiceController extends Controller
'error' => false,
'message' => 'Đã gửi yêu cầu xóa snapshot. Quá trình sẽ mất 1-2 phút, vui lòng chờ đợi.'
]);
} catch (\Exception $e) {
Log::error('❌ Lỗi khi xóa snapshot', [
'product_id' => $request->product_id ?? 'not_provided',
@@ -710,7 +712,6 @@ class ServiceController extends Controller
'error' => false,
'message' => 'Đã gửi yêu cầu khôi phục snapshot. Quá trình sẽ mất 2-3 phút, vui lòng chờ đợi.'
]);
} catch (\Exception $e) {
Log::error('❌ Lỗi khi khôi phục snapshot', [
'product_id' => $request->product_id ?? 'not_provided',
@@ -930,6 +931,183 @@ class ServiceController extends Controller
}
}
public function reinstallVM(Request $request, vCenter $vCenterService)
{
try {
// Debug: Log request data
Log::info('reinstallVM called', [
'request_data' => $request->all(),
'user_id' => customer()?->id ?? 'not_logged_in'
]);
$user = customer();
if (!$user) {
Log::warning('User not logged in for reinstallVM');
return response()->json([
'error' => true,
'message' => __('Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.')
], 401);
}
$validator = Validator::make($request->all(), [
'invoice_id' => 'required|integer',
]);
if ($validator->fails()) {
Log::warning('Validation failed for reinstallVM', [
'errors' => $validator->errors()->toArray()
]);
return response()->json([
'error' => true,
'message' => __('Dữ liệu không hợp lệ'),
'errors' => $validator->errors()
], 422);
}
// Debug: Log invoice lookup
Log::info('Looking for invoice', ['invoice_id' => $request->invoice_id]);
$invoice = Invoice::find($request->invoice_id);
// Debug: Log invoice result
Log::info('Invoice lookup result', [
'invoice_id' => $request->invoice_id,
'found' => $invoice ? 'yes' : 'no',
'invoice_data' => $invoice ? $invoice->toArray() : null
]);
if (!$invoice) {
return response()->json([
'error' => true,
'message' => __('Không tìm thấy hóa đơn')
], 404);
}
// Debug: Log product lookup
$invoiceItem = $invoice->invoiceItem->first();
Log::info('Invoice item lookup', [
'invoice_item_found' => $invoiceItem ? 'yes' : 'no',
'invoice_item_data' => $invoiceItem ? $invoiceItem->toArray() : null
]);
$productId = $invoiceItem?->getProductAttribute()?->id;
Log::info('Product lookup', [
'product_id' => $productId,
'product_data' => $invoiceItem?->getProductAttribute()?->toArray() ?? null
]);
$vmware = $productId;
$osId = $request->os_id;
$userId = $user->id;
Log::info('VM lookup parameters', [
'vmware_id' => $vmware?->vmware_id ?? 'null',
'os_id' => $osId,
'user_id' => $userId
]);
// Tìm product và kiểm tra quyền sở hữu
$vm = ModuleVmware::where('vmware_id', $vmware->vmware_id)
->where('customer_id', $userId)
->first();
Log::info('VM lookup result', [
'vm_found' => $vm ? 'yes' : 'no',
'vm_data' => $vm ? $vm->toArray() : null
]);
if (!$vm) {
return response()->json([
'error' => true,
'message' => __('Không tìm thấy VPS hoặc bạn không có quyền truy cập')
], 404);
}
// Kiểm tra OS có tồn tại và hợp lệ không
$os = Os::find($osId);
if (!$os) {
return response()->json([
'error' => true,
'message' => __('Hệ điều hành không tồn tại')
], 404);
}
// Kiểm tra OS có được phép cho VPS này không
$allowedOs = $vm->operatingSystems()->where('os.id', $osId)->first();
if (!$allowedOs) {
return response()->json([
'error' => true,
'message' => __('Hệ điều hành này không được phép cho VPS này')
], 403);
}
// Debug: Log before vCenter call
Log::info('About to call vCenter DeleteVirtualMachine', [
'vmware_id' => $vm->vmware_id,
'os_id' => $osId
]);
// Gọi vCenter service để xóa VM
$result = $vCenterService->DeleteVirtualMachine($vm->vmware_id);
// Debug: Log vCenter result
Log::info('vCenter DeleteVirtualMachine result', [
'result' => $result,
'is_array' => is_array($result),
'has_error_key' => is_array($result) && isset($result['error']),
'error_value' => is_array($result) ? ($result['error'] ?? 'not_set') : 'not_array'
]);
if (is_array($result) && isset($result['error']) && $result['error'] === false) {
// Cập nhật OS trong database
$vm->update([
'os_id' => $osId
]);
// Clear VM info cache
Cache::forget('vm_info_' . $vm->vmware_id);
// Log hoạt động
Log::info('VM reinstall initiated', [
'user_id' => $userId,
'product_id' => $vm->id,
'old_os_id' => $vm->os_id,
'new_os_id' => $osId,
'os_name' => $os->version
]);
Log::info('Returning success response');
return response()->json([
'error' => false,
'message' => __('Yêu cầu cài lại máy ảo đã được gửi thành công. Quá trình sẽ mất 5-10 phút.')
]);
} else {
$msg = is_array($result) && isset($result['data']) ? $result['data'] : __('Không thể cài lại máy ảo');
Log::warning('vCenter call failed', [
'result' => $result,
'message' => $msg
]);
return response()->json([
'error' => true,
'message' => $msg
], 500);
}
} catch (\Exception $e) {
Log::error('Lỗi khi cài lại máy ảo', [
'user_id' => $user->id ?? 'guest',
'product_id' => $request->product_id ?? 'not_provided',
'os_id' => $request->os_id ?? 'not_provided',
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
return response()->json([
'error' => true,
'message' => __('Có lỗi xảy ra khi cài lại máy ảo')
], 500);
}
}
/**
* Sanitize input data
*/
@@ -1016,7 +1194,6 @@ class ServiceController extends Controller
}
return $result['data'] ?? [];
} catch (\Exception $e) {
Log::error('Lỗi khi lấy snapshot từ vCenter', [
'product_id' => $product->id,
+289 -43
View File
@@ -7,6 +7,10 @@ use App\Models\Os;
use App\Models\OsGroup;
use App\Models\VPS;
use App\Models\InvoiceItem;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use App\Models\Invoice;
use App\Models\ModuleVmware;
class VPSReinstallModal extends Component
{
@@ -17,6 +21,13 @@ class VPSReinstallModal extends Component
public $operatingSystems = [];
public $currentOs;
public $invoiceId;
public $isLoading = false;
public $selectedOsDetails = null;
public $vpsInfo = null;
public $moduleVmware = null;
public $vpsIpAddress = null;
public $invoiceItem = null;
public $invoice = null;
protected $listeners = ['showOsModal' => 'loadOsData'];
@@ -24,6 +35,7 @@ class VPSReinstallModal extends Component
{
$this->productId = $productId;
$this->invoiceId = $invoiceId;
$this->operatingSystems = collect(); // Initialize as empty collection
if ($productId) {
$this->loadOsData($productId);
}
@@ -32,70 +44,304 @@ class VPSReinstallModal extends Component
public function loadOsData($productId)
{
$this->productId = $productId;
// Get the VPS product
$vps = VPS::with('operatingSystems.osGroup')->find($productId);
if (!$vps) {
return;
}
$this->isLoading = true;
// Get OS groups that are assigned to this VPS product
$osGroupIds = $vps->operatingSystems->pluck('osGroup.id')->filter()->unique();
$this->osGroups = OsGroup::with(['os' => function($query) use ($vps) {
// Only get OS versions that are assigned to this specific VPS product
$query->whereHas('vpsProducts', function($q) use ($vps) {
$q->where('product_id', $vps->id)
->where('product_type', 4);
})->where('status', 1);
}])
->whereIn('id', $osGroupIds)
->where('status', 1)
->get();
try {
// Get the VPS product
$vps = VPS::with('operatingSystems.osGroup')->find($productId);
// Get current OS from invoice_item
if ($this->invoiceId) {
$invoiceItem = InvoiceItem::where('invoice_id', $this->invoiceId)
->where('product_id', $productId)
->where('product_type', 4)
->with('os.osGroup')
->first();
if (!$vps) {
session()->flash('error', __('Không tìm thấy thông tin VPS.'));
return;
}
// Store VPS info for confirmation message
$this->vpsInfo = $vps;
// Get OS groups that are assigned to this VPS product
$osGroupIds = $vps->operatingSystems->pluck('osGroup.id')->filter()->unique();
$this->osGroups = OsGroup::with(['os' => function ($query) use ($vps) {
// Only get OS versions that are assigned to this specific VPS product
$query->whereHas('vpsProducts', function ($q) use ($vps) {
$q->where('product_id', $vps->id)
->where('product_type', 4);
})->where('status', 1);
}])
->whereIn('id', $osGroupIds)
->where('status', 1)
->get();
// Get current OS and ModuleVmware info from invoice_item
if ($this->invoiceId) {
$this->invoiceItem = InvoiceItem::where('invoice_id', $this->invoiceId)
->where('product_id', $productId)
->where('product_type', 4)
->with('os.osGroup')
->first();
$this->currentOs = $this->invoiceItem?->os;
$this->currentOs = $invoiceItem?->os;
// Debug InvoiceItem info first
Log::info('InvoiceItem debug info', [
'invoice_id' => $this->invoiceId,
'product_id' => $productId,
'product_type' => 4,
'invoice_item_found' => $this->invoiceItem ? 'yes' : 'no',
'invoice_item_id' => $this->invoiceItem?->id ?? 'null',
'invoice_item_relid' => $this->invoiceItem?->relid ?? 'null',
'invoice_item_type_id' => $this->invoiceItem?->type_id ?? 'null',
'invoice_item_product_id' => $this->invoiceItem?->product_id ?? 'null',
'invoice_item_product_type' => $this->invoiceItem?->product_type ?? 'null'
]);
// Get ModuleVmware info to access IP address
if ($this->invoiceItem) {
// Try to get ModuleVmware directly using invoice_id and customer_id
$this->invoice = Invoice::find($this->invoiceId);
if ($this->invoice && $this->invoice->customer_id) {
$this->moduleVmware = ModuleVmware::where('customer_id', $this->invoice->customer_id)
->where('order_id', $this->invoiceId)
->with('ipAddress')
->first();
// If not found by order_id, try to find by customer_id and product info
if (!$this->moduleVmware) {
$this->moduleVmware = ModuleVmware::where('customer_id', $this->invoice->customer_id)
->with('ipAddress')
->first();
}
}
// Try to get IP from vCenter API first, fallback to database
$this->vpsIpAddress = $this->getIPFromVCenter() ?? $this->moduleVmware?->ipAddress?->ip ?? null;
// Debug ModuleVmware info
Log::info('ModuleVmware debug info', [
'invoice_item_id' => $this->invoiceItem->id,
'invoice_item_relid' => $this->invoiceItem->relid,
'invoice_item_type_id' => $this->invoiceItem->type_id,
'invoice_customer_id' => $this->invoice?->customer_id ?? 'null',
'module_vmware' => $this->moduleVmware ? 'found' : 'not_found',
'module_vmware_id' => $this->moduleVmware?->id ?? 'null',
'module_vmware_name' => $this->moduleVmware?->name ?? 'null',
'module_vmware_customer_id' => $this->moduleVmware?->customer_id ?? 'null',
'module_ip_address_id' => $this->moduleVmware?->module_ip_address_id ?? 'null',
'ip_address_relationship' => $this->moduleVmware?->ipAddress ? 'found' : 'not_found',
'ip_address_from_db' => $this->moduleVmware?->ipAddress?->ip ?? 'null',
'ip_address_from_vcenter' => $this->vpsIpAddress ?? 'null'
]);
} else {
Log::warning('InvoiceItem not found', [
'invoice_id' => $this->invoiceId,
'product_id' => $productId,
'product_type' => 4
]);
}
}
Log::info('OS data loaded successfully', [
'product_id' => $productId,
'os_groups_count' => is_object($this->osGroups) ? $this->osGroups->count() : count($this->osGroups),
'current_os' => $this->currentOs ? $this->currentOs->id : null,
'module_vmware_id' => $this->moduleVmware ? $this->moduleVmware->id : null,
'ip_address' => $this->moduleVmware?->ipAddress?->ip ?? 'N/A'
]);
} catch (\Exception $e) {
Log::error('Error loading OS data', [
'product_id' => $productId,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
session()->flash('error', __('Có lỗi xảy ra khi tải dữ liệu hệ điều hành.'));
} finally {
$this->isLoading = false;
}
}
public function updatedSelectedOsGroupId($value)
{
// Reset selected OS when changing group
$this->selectedOsId = null;
$this->selectedOsDetails = null;
$this->isLoading = true;
try {
if ($value) {
$this->operatingSystems = Os::where('os_group_id', $value)
->where('status', 1)
->whereHas('vpsProducts', function ($query) {
$query->where('product_id', $this->productId)
->where('product_type', 4);
})
->with('osGroup')
->get();
Log::info('Operating systems loaded for group', [
'os_group_id' => $value,
'os_count' => is_object($this->operatingSystems) ? $this->operatingSystems->count() : count($this->operatingSystems),
'selected_os_id' => $this->selectedOsId
]);
} else {
$this->operatingSystems = collect();
}
} catch (\Exception $e) {
Log::error('Error loading operating systems', [
'os_group_id' => $value,
'error' => $e->getMessage()
]);
session()->flash('error', __('Có lỗi xảy ra khi tải danh sách phiên bản hệ điều hành.'));
$this->operatingSystems = collect();
} finally {
$this->isLoading = false;
}
}
public function updatedSelectedOsId($value)
{
Log::info('Selected OS ID updated', [
'selected_os_id' => $value,
'is_loading' => $this->isLoading
]);
// Store selected OS details for confirmation message
if ($value) {
$this->operatingSystems = Os::where('os_group_id', $value)
->where('status', 1)
->whereHas('vpsProducts', function($query) {
$query->where('product_id', $this->productId)
->where('product_type', 4);
})
->get();
$this->selectedOsDetails = Os::with('osGroup')->find($value);
Log::info('OS details loaded', [
'os_id' => $value,
'os_name' => $this->selectedOsDetails?->osGroup?->name ?? 'null',
'os_version' => $this->selectedOsDetails?->version ?? 'null'
]);
} else {
$this->operatingSystems = [];
$this->selectedOsDetails = null;
}
}
public function confirmReinstall()
{
Log::info('confirmReinstall called', [
'selected_os_id' => $this->selectedOsId,
'invoice_id' => $this->invoiceId,
'is_loading' => $this->isLoading
]);
if (!$this->selectedOsId) {
session()->flash('error', __('Please select an operating system.'));
session()->flash('error', __('Vui lòng chọn hệ điều hành.'));
return;
}
// Here you would implement the reinstall logic
// For now, just show a success message
session()->flash('success', __('Operating system reinstall initiated.'));
// Close modal
$this->dispatchBrowserEvent('close-modal', ['name' => 'reinstall-vm']);
if (!$this->invoiceId) {
session()->flash('error', __('Thiếu thông tin hóa đơn.'));
return;
}
$this->isLoading = true;
try {
$response = Http::withoutVerifying()
->withHeaders([
'X-CSRF-TOKEN' => csrf_token(),
'Accept' => 'application/json',
'Content-Type' => 'application/json',
])
->post(route('service.reinstall.vm'), [
'invoice_id' => $this->invoiceId,
'os_id' => $this->selectedOsId,
]);
Log::info('Reinstall response', [
'status' => $response->status(),
'body' => $response->body()
]);
if ($response->successful()) {
session()->flash('success', __('Yêu cầu cài lại hệ điều hành đã được gửi thành công.'));
$this->dispatch('close-modal', ['name' => 'reinstall-vm']);
} else {
$errorMessage = $response->json('message') ?? __('Có lỗi xảy ra khi gửi yêu cầu.');
session()->flash('error', $errorMessage);
}
} catch (\Exception $e) {
Log::error('Error during reinstall request', [
'invoice_id' => $this->invoiceId,
'os_id' => $this->selectedOsId,
'error' => $e->getMessage()
]);
session()->flash('error', __('Có lỗi xảy ra khi gửi yêu cầu cài lại.'));
} finally {
$this->isLoading = false;
}
}
/**
* Get IP address from vCenter API
*/
private function getIPFromVCenter()
{
try {
if (!$this->moduleVmware || !$this->moduleVmware->vmware_id) {
Log::warning('No ModuleVmware or vmware_id found for vCenter IP lookup');
return null;
}
// Get vCenter configuration from ModuleVmware
$vcenter = $this->moduleVmware->ipAddress?->host?->datacenter?->vCenter;
if (!$vcenter) {
Log::warning('No vCenter configuration found for ModuleVmware', [
'module_vmware_id' => $this->moduleVmware->id,
'vmware_id' => $this->moduleVmware->vmware_id
]);
return null;
}
// Initialize vCenter service
$vCenterService = new \App\Http\Services\vCenter();
// Login to vCenter
$loginSuccess = $vCenterService->loginServer($vcenter);
if (!$loginSuccess) {
Log::warning('Failed to login to vCenter for IP lookup', [
'vmware_id' => $this->moduleVmware->vmware_id,
'vcenter_id' => $vcenter->id
]);
return null;
}
// Get IP address from vCenter
$ipInfo = $vCenterService->GetIPAddressVirtualMachine($this->moduleVmware->vmware_id);
Log::info('vCenter IP lookup result', [
'vmware_id' => $this->moduleVmware->vmware_id,
'ip_info' => $ipInfo
]);
if (is_array($ipInfo) && isset($ipInfo['error']) && $ipInfo['error'] === false) {
// Try different possible structures
if (isset($ipInfo['data']['ip_address'])) {
return $ipInfo['data']['ip_address'];
} elseif (isset($ipInfo['data']['value']['ip_address'])) {
return $ipInfo['data']['value']['ip_address'];
}
}
Log::warning('No valid IP address found in vCenter response', [
'vmware_id' => $this->moduleVmware->vmware_id,
'ip_info' => $ipInfo
]);
return null;
} catch (\Exception $e) {
Log::error('Error getting IP from vCenter', [
'vmware_id' => $this->moduleVmware?->vmware_id ?? 'unknown',
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
]);
return null;
}
}
public function render()