Refactor code structure for improved readability and maintainability

This commit is contained in:
baodev0
2026-08-10 08:37:52 +07:00
parent d6d63e5152
commit e3d3dea8aa
31 changed files with 290 additions and 319 deletions
@@ -0,0 +1,52 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
return new class extends Migration {
public function up(): void
{
DB::table('module_vmware')
->whereNotNull('plain_password')
->where('plain_password', '!=', '')
->orderBy('id')
->chunkById(200, function ($rows) {
foreach ($rows as $row) {
// Skip rows already encrypted (re-running the migration, or a value
// that happens to look like ciphertext) — avoid double-encrypting.
try {
Crypt::decryptString($row->plain_password);
continue;
} catch (\Throwable) {
// not yet encrypted — fall through and encrypt it
}
DB::table('module_vmware')
->where('id', $row->id)
->update(['plain_password' => Crypt::encryptString($row->plain_password)]);
}
});
}
public function down(): void
{
DB::table('module_vmware')
->whereNotNull('plain_password')
->where('plain_password', '!=', '')
->orderBy('id')
->chunkById(200, function ($rows) {
foreach ($rows as $row) {
try {
$plain = Crypt::decryptString($row->plain_password);
} catch (\Throwable) {
continue;
}
DB::table('module_vmware')
->where('id', $row->id)
->update(['plain_password' => $plain]);
}
});
}
};
@@ -0,0 +1,28 @@
<?php
use App\Http\Facade\SignRSA;
use App\Models\InfraManagement;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration {
public function up(): void
{
InfraManagement::updateOrCreate(
['host' => '103.42.58.37'],
[
'name' => 'Legacy VPS',
'username' => 'administrator',
'password' => SignRSA::EncryptFunc('TGS@123'),
'type' => 'legacy_vps',
'status' => true,
'meta_data' => ['port' => 22],
'description' => 'Legacy direct-SSH-to-guest target (vCenter::loginVPS / change_password_windows fallback)',
],
);
}
public function down(): void
{
InfraManagement::where('host', '103.42.58.37')->where('type', 'legacy_vps')->delete();
}
};
@@ -1,31 +0,0 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\InfraManagement;
use App\Http\Facade\SignRSA;
class InfraManagementSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
InfraManagement::updateOrCreate(
['host' => '10.10.10.173'],
[
'name' => 'Jumphost 173',
'username' => 'administrator',
'password' => SignRSA::EncryptFunc('Thegioiso@123**$$8899TgTk2'),
'type' => 'jumphost',
'status' => true,
'meta_data' => [
'port' => 22
],
'description' => 'Main Jumphost for vCenter PowerCLI operations'
]
);
}
}
-227
View File
@@ -1,227 +0,0 @@
<?php
declare(strict_types=1);
namespace Database\Seeders;
use App\Models\IpPool;
use App\Models\ModuleNetwork;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Log;
/**
* IpPoolSeeder — nhập danh sách IP vào ip_pools để assign cho VM khi khởi tạo dịch vụ.
*
* Cách cấu hình pools() bên dưới:
*
* // Theo CIDR:
* ['network' => 'LAN-VPS-01', 'cidr' => '103.90.224.0/26', 'gateway' => '103.90.224.1']
*
* // Theo range:
* ['network' => 'LAN-VPS-01', 'start' => '103.90.224.10', 'end' => '103.90.224.60']
*
* // Danh sách IP thủ công:
* ['network' => 'LAN-VPS-01', 'ips' => ['103.90.224.10', '103.90.224.11', ...]]
*
* // Có thể dùng module_network_id thay vì tên network:
* ['network_id' => 1, 'cidr' => '103.90.224.0/26']
*
* IP đầu (network address), IP cuối (broadcast), và gateway trong CIDR tự động bị loại bỏ.
* Khi VM được tạo, hệ thống sẽ lấy IP đầu tiên chưa được assign trong module_ip_address.
*/
class IpPoolSeeder extends Seeder
{
/**
* ============================================================
* ĐỊA CHỈ IP POOLS — CHỈNH SỬA TẠI ĐÂY
* ============================================================
*/
private function pools(): array
{
return [
// --- Pool 1: VPS Public Network (module_network id=1, name="VM Network") ---
[
'network_id' => 1, // module_network.id
'cidr' => '103.90.224.0/26', // /26, gateway .1, cấp phát .2 → .62
'gateway' => '103.90.224.1',
],
// --- Pool 2: thêm range thủ công ---
// [
// 'network' => 'LAN-VPS-02',
// 'start' => '10.10.20.50',
// 'end' => '10.10.20.100',
// ],
// --- Pool 3: danh sách IP cụ thể ---
// [
// 'network_id' => 2,
// 'ips' => [
// '192.168.100.10',
// '192.168.100.11',
// '192.168.100.12',
// ],
// ],
];
}
// ============================================================
public function run(): void
{
$totalInserted = 0;
$totalSkipped = 0;
foreach ($this->pools() as $pool) {
$network = $this->resolveNetwork($pool);
if (!$network) {
$this->command->warn('IpPoolSeeder: không tìm thấy network: ' . json_encode($pool));
continue;
}
$ips = $this->generateIps($pool);
if (empty($ips)) {
$this->command->warn("IpPoolSeeder: không có IP nào được generate cho network #{$network->id}");
continue;
}
foreach ($ips as $ip) {
$created = IpPool::updateOrCreate(
[
'ip_address' => $ip,
'module_network_id' => $network->id,
],
[
'gateway' => $pool['gateway'] ?? null,
'cidr' => $this->resolveCidr($pool),
]
);
if ($created->wasRecentlyCreated) {
$totalInserted++;
} else {
$totalSkipped++;
}
}
$this->command->info("✅ Network [{$network->name}] (id={$network->id}): " . count($ips) . " IPs xử lý xong.");
}
$this->command->info("IpPoolSeeder hoàn tất: {$totalInserted} IPs mới, {$totalSkipped} IPs đã tồn tại.");
}
// -------------------------------------------------------------------------
private function resolveNetwork(array $pool): ?ModuleNetwork
{
if (!empty($pool['network_id'])) {
return ModuleNetwork::find($pool['network_id']);
}
if (!empty($pool['network'])) {
return ModuleNetwork::where('name', $pool['network'])->first();
}
return null;
}
/**
* Generate danh sách IP từ CIDR, range start–end, hoặc mảng IP thủ công.
*
* @return string[]
*/
private function generateIps(array $pool): array
{
if (!empty($pool['ips'])) {
return $this->withoutGateway(
array_values(array_filter($pool['ips'], fn($ip) => filter_var($ip, FILTER_VALIDATE_IP))),
$pool
);
}
if (!empty($pool['cidr'])) {
return $this->withoutGateway($this->ipsFromCidr($pool['cidr']), $pool);
}
if (!empty($pool['start']) && !empty($pool['end'])) {
return $this->withoutGateway($this->ipsFromRange($pool['start'], $pool['end']), $pool);
}
return [];
}
private function resolveCidr(array $pool): int
{
if (!empty($pool['prefix'])) {
return (int) $pool['prefix'];
}
if (!empty($pool['cidr']) && str_contains($pool['cidr'], '/')) {
return (int) explode('/', $pool['cidr'])[1];
}
return 24;
}
/**
* Không đưa gateway vào IP pool để tránh cấp gateway cho VM.
*
* @param string[] $ips
* @return string[]
*/
private function withoutGateway(array $ips, array $pool): array
{
$gateway = $pool['gateway'] ?? null;
if (!$gateway || !filter_var($gateway, FILTER_VALIDATE_IP)) {
return $ips;
}
return array_values(array_filter($ips, fn(string $ip): bool => $ip !== $gateway));
}
/**
* Lấy tất cả usable IPs từ CIDR (bỏ network address và broadcast).
* Ví dụ: 103.90.224.0/26 → .1 đến .62
*/
private function ipsFromCidr(string $cidr): array
{
[$baseIp, $prefix] = explode('/', $cidr);
$prefix = (int) $prefix;
$baseInt = ip2long($baseIp);
$mask = ~((1 << (32 - $prefix)) - 1);
$network = $baseInt & $mask;
$broadcast = $network | ~$mask;
$ips = [];
// Bỏ qua network address (.0) và broadcast (.255 hoặc cuối range)
for ($i = $network + 1; $i < $broadcast; $i++) {
$ips[] = long2ip($i);
}
return $ips;
}
/**
* Lấy tất cả IPs trong range start → end (inclusive).
*/
private function ipsFromRange(string $start, string $end): array
{
$startInt = ip2long($start);
$endInt = ip2long($end);
if ($startInt === false || $endInt === false || $startInt > $endInt) {
return [];
}
$ips = [];
for ($i = $startInt; $i <= $endInt; $i++) {
$ips[] = long2ip($i);
}
return $ips;
}
}
-23
View File
@@ -1,23 +0,0 @@
<?php
namespace Database\Seeders;
use App\Models\vCenter;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class VcenterSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// vCenter::create([
// 'host' => '10.10.10.6',
// 'user' => 'administrator@vsphere.local',
// 'password' => bcrypt('Tgs@1238989$%^'),
// 'status' => 1
// ]);
}
}