- Introduced a new method `resolveVCenterFromProduct` in `SnapshotService` to streamline vCenter resolution from product data. - Updated `CreateSnapshot`, `RemoveSnapshot`, and `RevertSnapshot` jobs to utilize the new vCenter resolution method. - Enhanced the `VmController` to support UUID-based service identification for VM operations. - Added new actions for changing VM IP and RDP port, encapsulating the logic for these operations. - Improved error handling and logging for VM operations, including detailed responses for API consumers. - Removed unnecessary relationships in model queries to optimize performance.
160 lines
5.9 KiB
PHP
160 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace App\Jobs\VirtualMachine\Snapshot;
|
|
|
|
use App\Events\NotificationStatus;
|
|
use App\Http\Services\Telegram;
|
|
use App\Http\Services\vCenter as ServiceVCenter;
|
|
use App\Models\ModuleSnapshot;
|
|
use App\Models\ModuleVmware;
|
|
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 RevertSnapshot implements ShouldQueue
|
|
{
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
|
protected $productId;
|
|
protected $snapshotId;
|
|
protected $telegram;
|
|
|
|
/**
|
|
* Create a new job instance.
|
|
*
|
|
* @param int $productId
|
|
* @param int $snapshotId
|
|
* @return void
|
|
*/
|
|
public function __construct($productId = 0, $snapshotId = 0)
|
|
{
|
|
$this->productId = $productId;
|
|
$this->snapshotId = $snapshotId;
|
|
$this->telegram = new Telegram();
|
|
}
|
|
|
|
/**
|
|
* Execute the job.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function handle(ServiceVCenter $serviceVCenter)
|
|
{
|
|
try {
|
|
// Load product and snapshot
|
|
$product = ModuleVmware::find($this->productId);
|
|
$snapshot = ModuleSnapshot::find($this->snapshotId);
|
|
|
|
if (!$product || !$snapshot) {
|
|
throw new \Exception("Không tìm thấy thông tin VPS hoặc snapshot");
|
|
}
|
|
|
|
// Resolve vCenter using helper method
|
|
$vcenter = $serviceVCenter->resolveVCenterFromProduct($product);
|
|
|
|
if (!$vcenter) {
|
|
throw new \Exception("VPS không có thông tin vCenter được cấu hình");
|
|
}
|
|
|
|
// Set vCenter connection info
|
|
$serviceVCenter->token = $vcenter->token;
|
|
$serviceVCenter->apiUri = $vcenter->host;
|
|
|
|
Log::info('🔄 Bắt đầu khôi phục snapshot', [
|
|
'product_id' => $product->id,
|
|
'snapshot_id' => $snapshot->id,
|
|
'snapshot_name' => $snapshot->name,
|
|
'vcenter_host' => $vcenter->host
|
|
]);
|
|
|
|
// Attempt to revert snapshot
|
|
$result = $serviceVCenter->RevertSnapShot($product, $snapshot->snapshot_ref ?? $snapshot->name);
|
|
|
|
// Handle re-login if needed
|
|
if ($result === 'Login_Again') {
|
|
Log::info('🔑 Cần đăng nhập lại vCenter');
|
|
$token = $serviceVCenter->loginServer($vcenter);
|
|
if ($token) {
|
|
$vcenter->update(['token' => $token]);
|
|
$serviceVCenter->token = $token;
|
|
$result = $serviceVCenter->RevertSnapShot($product, $snapshot->snapshot_ref ?? $snapshot->name);
|
|
} else {
|
|
throw new \Exception("Không thể đăng nhập lại vào vCenter");
|
|
}
|
|
}
|
|
|
|
// Check for errors
|
|
if (is_array($result) && isset($result['error']) && $result['error']) {
|
|
$errorMessage = 'Lỗi khôi phục snapshot';
|
|
if (isset($result['message'])) {
|
|
$errorMessage .= ': ' . (is_array($result['message']) ? json_encode($result['message']) : $result['message']);
|
|
}
|
|
throw new \Exception($errorMessage);
|
|
}
|
|
|
|
if (is_string($result) && $result !== 'Login_Again') {
|
|
throw new \Exception("Lỗi khôi phục snapshot: {$result}");
|
|
}
|
|
|
|
Log::info('✅ Khôi phục snapshot thành công', [
|
|
'product_id' => $product->id,
|
|
'snapshot_name' => $snapshot->name
|
|
]);
|
|
|
|
// Send success notification
|
|
Event(new NotificationStatus("Khôi phục snapshot thành công cho VPS {$product->name}", true));
|
|
|
|
// Send Telegram notification
|
|
$this->telegram->SendMessage(
|
|
"🔄 <b>SNAPSHOT REVERTED SUCCESSFULLY</b>\n\n" .
|
|
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" .
|
|
"🖥️ <b>Server:</b> `{$product->name}`\n" .
|
|
"📸 <b>Snapshot:</b> `{$snapshot->name}`\n" .
|
|
"👤 <b>Customer:</b> `#{$product->customer_id}`\n" .
|
|
"🆔 <b>VM ID:</b> `{$product->vmware_id}`\n" .
|
|
"⏰ <b>Reverted:</b> `" . now()->format('d/m/Y H:i:s') . "`\n" .
|
|
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" .
|
|
"💡 <b>Status:</b> ✅ Completed\n" .
|
|
"🔧 <b>Action:</b> Snapshot Revert\n" .
|
|
"📊 <b>Queue:</b> snapshots"
|
|
);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('❌ Lỗi khôi phục snapshot', [
|
|
'product_id' => $this->productId,
|
|
'snapshot_id' => $this->snapshotId,
|
|
'error' => $e->getMessage(),
|
|
'file' => $e->getFile(),
|
|
'line' => $e->getLine()
|
|
]);
|
|
|
|
throw $e; // Re-throw để kích hoạt failed method
|
|
}
|
|
}
|
|
|
|
public function failed(\Throwable $exception)
|
|
{
|
|
Log::error('❌ Job RevertSnapshot failed', [
|
|
'product_id' => $this->productId,
|
|
'snapshot_id' => $this->snapshotId,
|
|
'error' => $exception->getMessage(),
|
|
'trace' => $exception->getTraceAsString()
|
|
]);
|
|
|
|
// Send failure notification
|
|
Event(new NotificationStatus("Lỗi khôi phục snapshot: {$exception->getMessage()}", false));
|
|
|
|
// Send Telegram error notification
|
|
$this->telegram->SendErrorMessage([
|
|
'job_name' => 'RevertSnapshot',
|
|
'product_id' => $this->productId,
|
|
'snapshot_id' => $this->snapshotId,
|
|
'error' => $exception->getMessage(),
|
|
'trace' => $exception->getTraceAsString()
|
|
]);
|
|
}
|
|
}
|