Update source into github

This commit is contained in:
pbao9
2025-07-24 16:18:27 +07:00
parent 41419358dd
commit 69851ac7bc
2642 changed files with 284095 additions and 0 deletions
@@ -0,0 +1,38 @@
<?php
namespace App\Jobs\VirtualMachine\Sync;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SyncAllPackage implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
SyncDatacenter::dispatchSync();
SyncHost::dispatchSync();
SyncDatastore::dispatchSync();
SyncNetwork::dispatchSync();
SyncFolder::dispatchSync();
}
}
@@ -0,0 +1,119 @@
<?php
namespace App\Jobs\VirtualMachine\Sync;
use App\Http\Services\Telegram;
use App\Http\Services\vCenter as ServiceVCenter;
use App\Models\ModuleDatacenter;
use App\Models\vCenter;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Throwable;
class SyncDatacenter implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $vCenter = null;
protected $data = null;
protected Telegram $telegram;
/**
* Create a new job instance.
*/
public function __construct()
{
$this->data = vCenter::select('id', 'host', 'user', 'password', 'token')->get();
$this->vCenter = new ServiceVCenter;
$this->telegram = new Telegram();
}
/**
* Execute the job.
*/
public function handle()
{
try {
$loginResults = [];
foreach ($this->data as $item) {
$this->vCenter->apiUri = $item->host;
// Always login to get a fresh token
$token = $this->vCenter->loginServer($item);
if ($token) {
$item->token = $token;
$item->save();
$this->vCenter->token = $token;
$loginResults[] = [
'host' => $item->host,
'user' => $item->user,
'token' => $token,
];
} else {
$this->vCenter->token = null;
}
// If login failed, skip
if (!$this->vCenter->token) {
continue;
}
// Attempt to get datacenters
$getDatacenter = $this->vCenter->getAllDatacenter();
// If token expired, retry login and get datacenter again
if ($getDatacenter === 'Login_Again') {
$token = $this->vCenter->loginServer($item);
if ($token) {
$item->token = $token;
$item->save();
$this->vCenter->token = $token;
$loginResults[] = [
'host' => $item->host,
'user' => $item->user,
'token' => $token,
];
$getDatacenter = $this->vCenter->getAllDatacenter();
}
}
// Ensure valid response
if (!is_array($getDatacenter)) {
continue;
}
// Save new datacenters
foreach ($getDatacenter as $_item) {
if (!isset($_item['datacenter']) || !isset($_item['name'])) {
continue; // skip malformed items
}
$exists = ModuleDatacenter::where('datacenter_id', $_item['datacenter'])->first();
if (!$exists) {
ModuleDatacenter::create([
'name' => $_item['name'],
'datacenter_id' => $_item['datacenter'],
'vcenter_id' => $item->id
]);
}
}
}
// Notify success via Telegram
$this->telegram->SendJobRunInfo('SyncDataCenter', 'Success', [
'message' => 'Sync datacenter completed successfully',
'synced_vcenters' => $this->data->count(),
'login_results' => $loginResults,
]);
} catch (Throwable $e) {
// Gửi log lỗi qua Telegram
$this->telegram->SendJobRunInfo('SyncDataCenter', 'Failed', [
'error' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
]);
}
}
}
@@ -0,0 +1,146 @@
<?php
namespace App\Jobs\VirtualMachine\Sync;
use App\Http\Services\Telegram;
use App\Http\Services\vCenter as ServiceVCenter;
use App\Models\ModuleDatacenter;
use App\Models\ModuleDatastore;
use App\Models\ModuleHost;
use App\Models\vCenter;
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 SyncDatastore implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $vCenter = null;
protected $data = null;
protected Telegram $telegram;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
$this->data = vCenter::select('id', 'host', 'user', 'password', 'token')->get();
$this->vCenter = new ServiceVCenter;
$this->telegram = new Telegram();
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
try {
foreach ($this->data as $item) {
$this->vCenter->apiUri = $item->host;
if (!$item->token) {
$token = $this->vCenter->loginServer($item);
if ($token) {
vCenter::where('id', $item->id)->update(['token' => $token]);
$this->vCenter->token = $token;
}
}
$this->vCenter->token = $item->token;
if (!$this->vCenter->token) {
continue;
}
$dataCenter = ModuleDatacenter::where('vcenter_id', $item->id)->select('id', 'datacenter_id')->get();
Log::info('Datacenter SyncDatastore', ['data' => $dataCenter]);
foreach ($dataCenter as $_item) {
$allHost = ModuleHost::where('module_datacenter_id', $_item->id)->select('id', 'name')->get();
Log::info('Allhost Data', ['data' => $allHost]);
if ($allHost) {
foreach ($allHost as $hostItem) {
$datastore = $this->vCenter->loadDatastore($item, $hostItem->name);
Log::info('Datastore', ['data' => $datastore]);
if ($datastore === "Login_Again") {
$token = $this->vCenter->loginServer($item);
if ($token) {
vCenter::where('id', $item->id)->update(['token' => $token]);
$this->vCenter->token = $token;
}
}
$datastore = $this->vCenter->loadDatastore($item, $hostItem->name);
if ($datastore) {
foreach ($datastore as $_subItem) {
if (!ModuleDatastore::where('datastore', $_subItem['datastore'])->first()) {
$template = $this->vCenter->getAllDataStore();
if ($template) {
ModuleDatastore::create([
'name' => $_subItem['name'],
'datastore' => $_subItem['datastore'],
'type' => $_subItem['type'],
'space' => floor($_subItem['free_space'] / 1073741824),
'module_host_id' => $hostItem->id
]);
ModuleHost::where('id', $hostItem->id)->update(['template' => $template]);
} else {
ModuleDatastore::create([
'name' => $_subItem['name'],
'datastore' => $_subItem['datastore'],
'type' => $_subItem['type'],
'space' => floor($_subItem['free_space'] / 1073741824),
'module_host_id' => $hostItem->id
]);
}
}
}
}
}
}
}
}
// Notify success via Telegram
$this->telegram->SendJobRunInfo('SyncDatastore', 'Success', [
'message' => 'Sync datastore completed successfully',
'synced_vcenters' => $this->data->count(),
]);
} catch (\Throwable $exception) {
// Ghi log Laravel
Log::error('SyncDatastore Job failed', [
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Gửi log lỗi qua Telegram
$this->telegram->SendJobRunInfo('SyncDatastore', 'Failed', [
'error' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]);
// Quăng lại lỗi để Laravel xử lý retry/failure
throw $exception;
}
}
}
@@ -0,0 +1,91 @@
<?php
namespace App\Jobs\VirtualMachine\Sync;
use App\Http\Services\vCenter as ServiceVCenter;
use App\Models\ModuleDatacenter;
use App\Models\ModuleFolder;
use App\Models\vCenter;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SyncFolder implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $vCenter = null;
protected $data = null;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
$this->data = vCenter::select('id', 'host', 'user', 'password', 'token')->get();
$this->vCenter = new ServiceVCenter;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
foreach ($this->data as $item) {
$this->vCenter->apiUri = $item->host;
if (!$item->token) {
$token = $this->vCenter->loginServer($item);
if ($token) {
vCenter::where('id', $item->id)->update(['token' => $token]);
$this->vCenter->token = $token;
}
}
$this->vCenter->token = $item->token;
if (!$this->vCenter->token) {
continue;
}
$dataCenter = ModuleDatacenter::where('vcenter_id', $item->id)->select('id', 'datacenter_id')->get();
foreach ($dataCenter as $_item) {
$folder = $this->vCenter->getAllFolder($_item['datacenter_id']);
if ($folder === "Login_Again") {
$token = $this->vCenter->loginServer($item);
if ($token) {
vCenter::where('id', $item->id)->update(['token' => $token]);
$this->vCenter->token = $token;
}
}
$folder = $this->vCenter->getAllFolder($_item['datacenter_id']);
if ($folder) {
foreach ($folder as $_subItem) {
if (!ModuleFolder::where('folder', $_subItem['folder'])->first()) {
ModuleFolder::create([
'name' => $_subItem['name'],
'folder' => $_subItem['folder'],
'type' => $_subItem['type'],
'module_datacenter_id' => $_item['id']
]);
}
}
}
}
}
// Notify success via Telegram
(new \App\Http\Services\Telegram())->SendJobRunInfo('SyncFolder', 'Success', [
'message' => 'Sync folder completed successfully',
'synced_vcenters' => $this->data->count(),
]);
}
}
+126
View File
@@ -0,0 +1,126 @@
<?php
namespace App\Jobs\VirtualMachine\Sync;
use App\Http\Services\Telegram;
use App\Http\Services\vCenter as ServiceVCenter;
use App\Models\ModuleDatacenter;
use App\Models\ModuleHost;
use App\Models\vCenter;
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 SyncHost implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $vCenter = null;
protected $data = null;
protected Telegram $telegram;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
$this->data = vCenter::select('id', 'host', 'user', 'password', 'token')->get();
$this->vCenter = new ServiceVCenter;
$this->telegram = new Telegram();
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
try {
foreach ($this->data as $item) {
$this->vCenter->apiUri = $item->host;
if (!$item->token) {
$token = $this->vCenter->loginServer($item);
if ($token) {
vCenter::where('id', $item->id)->update(['token' => $token]);
$this->vCenter->token = $token;
}
}
$this->vCenter->token = $item->token;
if (!$this->vCenter->token) {
continue;
}
$dataCenter = ModuleDatacenter::where('vcenter_id', $item->id)
->select('id', 'datacenter_id')
->get();
foreach ($dataCenter as $_item) {
$host = $this->vCenter->getAllHost($_item['datacenter_id']);
if ($host === "Login_Again") {
$token = $this->vCenter->loginServer($item);
if ($token) {
vCenter::where('id', $item->id)->update(['token' => $token]);
$this->vCenter->token = $token;
}
}
$host = $this->vCenter->getAllHost($_item['datacenter_id']);
$template = $this->vCenter->getAllTemplate();
if ($host) {
foreach ($host as $_subItem) {
if (!ModuleHost::where('host_id', $_subItem['host'])->first()) {
ModuleHost::create([
'name' => $_subItem['name'],
'host_id' => $_subItem['host'],
'module_datacenter_id' => $_item['id'],
'template' => $template[0] ?? null,
]);
}
}
}
}
}
// Notify success via Telegram
$this->telegram->SendJobRunInfo('SyncHost', 'Success', [
'message' => 'Sync host completed successfully',
'synced_vcenters' => $this->data->count(),
]);
} catch (\Throwable $exception) {
// Ghi log Laravel
Log::error('SyncHost Job failed', [
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
// Gửi log lỗi qua Telegram
$this->telegram->SendJobRunInfo('SyncHost', 'Failed', [
'error' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
]);
// Quăng lại lỗi để Laravel xử lý retry/failure
throw $exception;
}
}
public function failed(\Throwable $exception)
{
Log::error('SyncHost Job failed', [
'error' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
]);
}
}
@@ -0,0 +1,105 @@
<?php
namespace App\Jobs\VirtualMachine\Sync;
use App\Http\Services\vCenter as ServiceVCenter;
use App\Models\ModuleDatacenter;
use App\Models\ModuleHost;
use App\Models\ModuleNetwork;
use App\Models\vCenter;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SyncNetwork implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $vCenter = null;
protected $data = null;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
$this->data = vCenter::select('id','host','user','password','token')->get();
$this->vCenter = new ServiceVCenter;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
foreach ($this->data as $item) {
$this->vCenter->apiUri = $item->host;
if (!$item->token) {
$token = $this->vCenter->loginServer($item);
if ($token) {
vCenter::where('id', $item->id)->update(['token' => $token]);
$this->vCenter->token = $token;
}
}
$this->vCenter->token = $item->token;
if (! $this->vCenter->token) {
continue;
}
$dataCenter = ModuleDatacenter::where('vcenter_id', $item->id)->select('id', 'datacenter_id')->get();
foreach ($dataCenter as $_item) {
$allHost = ModuleHost::where('module_datacenter_id',$_item->id)->select('id','name')->get();
if ($allHost)
{
foreach ($allHost as $hostItem)
{
$network = $this->vCenter->loadNetWork($item,$hostItem->name);
if ($network === "Login_Again") {
$token = $this->vCenter->loginServer($item);
if ($token)
{
vCenter::where('id',$item->id)->update(['token' => $token]);
$this->vCenter->token = $token;
$network = $this->vCenter->loadNetWork($item,$hostItem->name);
}
}
if ($network)
{
foreach ($network as $_subItem)
{
if (! ModuleNetwork::where('network',$_subItem['network'])->first())
{
ModuleNetwork::create([
'name' => $_subItem['name'],
'network' => $_subItem['network'],
'type' => $_subItem['type'],
'ModuleHost_id' => $hostItem->id
]);
}
}
}
}
}
}
}
// Notify success via Telegram
(new \App\Http\Services\Telegram())->SendJobRunInfo('SyncNetwork', 'Success', [
'message' => 'Sync network completed successfully',
'synced_vcenters' => $this->data->count(),
]);
}
}
@@ -0,0 +1,157 @@
<?php
namespace App\Jobs\VirtualMachine\Sync;
use App\Http\Services\vCenter;
use App\Models\Invoice;
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\Cache;
use Illuminate\Support\Facades\Log;
class UpdateVMInfoJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $timeout = 30;
public int $backoff = 60; // Wait 1 minute between retries
protected int $invoiceId;
protected string $vmId;
/**
* Create a new job instance.
*/
public function __construct(int $invoiceId, string $vmId)
{
$this->invoiceId = $invoiceId;
$this->vmId = $vmId;
}
/**
* Execute the job.
*/
public function handle(vCenter $vCenterService): void
{
try {
$invoice = Invoice::with([
'invoiceItem.os.osGroup',
'invoiceItem.addons'
])->find($this->invoiceId);
if (!$invoice) {
Log::warning('Invoice not found for VM info update', ['invoice_id' => $this->invoiceId]);
return;
}
$orderItem = $invoice->invoiceItem->first();
if (!$orderItem) {
Log::warning('Order item not found for invoice', ['invoice_id' => $this->invoiceId]);
return;
}
$product = $orderItem->getProductAttribute();
if (!$product) {
Log::warning('Product not found for order item', ['order_item_id' => $orderItem->id]);
return;
}
$host = $product->host;
$datacenter = $host?->datacenter;
$vcenter = $datacenter?->vcenter;
if (!$vcenter) {
Log::warning('vCenter not found for VM', ['vm_id' => $this->vmId]);
return;
}
// Login to vCenter
if (!$vCenterService->loginServer($vcenter)) {
Log::warning('Failed to login to vCenter', ['vm_id' => $this->vmId]);
return;
}
// Get VM details
$vmDetail = $vCenterService->GetDetailVirtualMachine($this->vmId);
if ($vmDetail['error'] === true) {
Log::warning('Failed to get VM details', ['vm_id' => $this->vmId, 'error' => $vmDetail['message'] ?? 'Unknown error']);
return;
}
$vmData = $vmDetail['data'];
// Get IP information
$ipInfo = $vCenterService->GetIPAddressVirtualMachine($this->vmId);
$ipAddress = 'N/A';
if ($ipInfo['error'] === false && !empty($ipInfo['data']['ip_addresses'])) {
$ipAddress = $ipInfo['data']['ip_addresses'][0] ?? 'N/A';
}
// Calculate hardware information
$cpuCount = $vmData['cpu']['count'] ?? 1;
$memoryMB = $vmData['memory']['size_MiB'] ?? 1024;
$memoryGB = round($memoryMB / 1024, 1);
$diskSizeGB = 0;
if (isset($vmData['disks']) && is_array($vmData['disks'])) {
foreach ($vmData['disks'] as $disk) {
$diskSizeGB += round(($disk['value']['capacity'] ?? 0) / (1024 * 1024 * 1024), 1);
}
}
$vmInfo = [
'vm_id' => $this->vmId,
'status' => $vmData['power_state'],
'ip_address' => $ipAddress,
'hostname' => $orderItem->server_name ?? 'Unknown',
'os' => $orderItem->os->osGroup->name ?? 'Unknown',
'cpu' => $cpuCount . ' cores',
'ram' => $memoryGB . ' GB',
'disk' => $diskSizeGB . ' GB',
'uptime' => 'N/A',
'last_updated' => now()->format('Y-m-d H:i:s'),
'vm_name' => $vmData['name'] ?? 'Unknown',
'vm_folder' => $vmData['folder'] ?? 'Unknown',
'vm_resource_pool' => $vmData['resource_pool'] ?? 'Unknown',
'vm_datastore' => $vmData['datastore'] ?? 'Unknown',
'vm_network' => $vmData['nics'][0]['backing']['network'] ?? 'Unknown',
'vm_mac' => $vmData['nics'][0]['mac_address'] ?? 'N/A',
'vm_guest_id' => $vmData['guest_ID'] ?? 'Unknown',
'vm_version' => $vmData['version'] ?? 'Unknown',
'vm_hardware_version' => $vmData['hardware']['version'] ?? 'Unknown',
];
// Cache the result for 5 minutes
$cacheKey = "vm_info_{$this->vmId}";
Cache::put($cacheKey, $vmInfo, 300);
Log::info('VM info updated successfully', ['vm_id' => $this->vmId]);
} catch (\Exception $e) {
Log::error('Error updating VM info', [
'vm_id' => $this->vmId,
'invoice_id' => $this->invoiceId,
'error' => $e->getMessage()
]);
// Don't throw exception to prevent job from failing completely
// The job will be retried automatically
}
}
/**
* Handle a job failure.
*/
public function failed(\Throwable $exception): void
{
Log::error('UpdateVMInfoJob failed', [
'vm_id' => $this->vmId,
'invoice_id' => $this->invoiceId,
'error' => $exception->getMessage()
]);
}
}