Files
portal-api/app/Jobs/VirtualMachine/Snapshot/CreateSnapshot.php
T
2025-07-24 16:18:27 +07:00

172 lines
6.2 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\ModuleSnapshotLimit;
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 CreateSnapshot implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $productId;
protected $telegram;
/**
* Create a new job instance.
*
* @param int $productId
* @return void
*/
public function __construct($productId = 0)
{
$this->productId = $productId;
$this->telegram = new Telegram();
}
/**
* Execute the job.
*
* @return void
*/
public function handle(ServiceVCenter $serviceVCenter)
{
try {
// Load product with necessary relationships
$product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')->find($this->productId);
if (!$product) {
throw new \Exception("Không tìm thấy thông tin VPS với ID: {$this->productId}");
}
// Kiểm tra cấu hình vCenter
if (!$product->ipAddress?->host?->datacenter?->vCenter) {
throw new \Exception("VPS không có thông tin vCenter được cấu hình");
}
$vcenter = $product->ipAddress->host->datacenter->vCenter;
// Set vCenter connection info
$serviceVCenter->token = $vcenter->token;
$serviceVCenter->apiUri = $vcenter->host;
Log::info('🔄 Bắt đầu tạo snapshot', [
'product_id' => $product->id,
'vmware_id' => $product->vmware_id,
'vcenter_host' => $vcenter->host
]);
// Attempt to create snapshot
$snapshot = $serviceVCenter->CreateSnapShot($product);
// Handle re-login if needed
if ($snapshot === '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;
$snapshot = $serviceVCenter->CreateSnapShot($product);
} else {
throw new \Exception("Không thể đăng nhập lại vào vCenter");
}
}
// Check for errors
if (is_array($snapshot) && isset($snapshot['error']) && $snapshot['error']) {
$errorMessage = 'Lỗi tạo snapshot';
if (isset($snapshot['message'])) {
$errorMessage .= ': ' . (is_array($snapshot['message']) ? json_encode($snapshot['message']) : $snapshot['message']);
}
throw new \Exception($errorMessage);
}
if (is_string($snapshot) && $snapshot !== 'Login_Again') {
throw new \Exception("Lỗi tạo snapshot: {$snapshot}");
}
// Get snapshot name from response
$snapshotName = null;
if (is_array($snapshot) && isset($snapshot['data'])) {
$snapshotName = $snapshot['data'];
} else {
$snapshotName = 'snapshot_' . now()->format('Y_m_d_H_i_s');
}
// Update snapshot limit counter
ModuleSnapshotLimit::where('customer_id', $product->customer_id)->increment('used', 1);
// Save snapshot to database
ModuleSnapshot::create([
'name' => $snapshotName,
'customer_id' => $product->customer_id,
'module_vmware_id' => $product->id
]);
Log::info('✅ Tạo snapshot thành công', [
'product_id' => $product->id,
'snapshot_name' => $snapshotName
]);
// Send success notification
Event(new NotificationStatus("Khởi tạo snapshot thành công cho VPS {$product->name}", true));
// Send Telegram notification
$this->telegram->SendMessage(
"🎉 <b>SNAPSHOT CREATED SUCCESSFULLY</b>\n\n" .
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" .
"🖥️ <b>Server:</b> `{$product->name}`\n" .
"📸 <b>Snapshot:</b> `{$snapshotName}`\n" .
"👤 <b>Customer:</b> `#{$product->customer_id}`\n" .
"🆔 <b>VM ID:</b> `{$product->vmware_id}`\n" .
"⏰ <b>Created:</b> `" . now()->format('d/m/Y H:i:s') . "`\n" .
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n" .
"💡 <b>Status:</b> ✅ Completed\n" .
"🔧 <b>Action:</b> Snapshot Creation\n" .
"📊 <b>Queue:</b> snapshots"
);
} catch (\Exception $e) {
Log::error('❌ Lỗi tạo snapshot', [
'product_id' => $this->productId,
'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 CreateSnapshot failed', [
'product_id' => $this->productId,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString()
]);
// Send failure notification
Event(new NotificationStatus("Lỗi tạo snapshot: {$exception->getMessage()}", false));
// Send Telegram error notification
$this->telegram->SendErrorMessage([
'job_name' => 'CreateSnapshot',
'product_id' => $this->productId,
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString()
]);
}
}