feat: add bulk delete with validation to IP Pool and update provisioning logic and email notifications

This commit is contained in:
pbao9
2026-05-13 15:41:56 +07:00
parent 1bbba4e158
commit ae3b681aaa
8 changed files with 242 additions and 101 deletions
@@ -9,6 +9,7 @@ use App\Models\IpPool;
use App\Models\ModuleIpAddress;
use App\Models\ModuleVmware;
use App\Models\Os;
use App\Http\Services\vCenter as vCenterService;
use App\Models\vCenter;
use App\Services\VsphereHostSshService;
use Illuminate\Bus\Queueable;
@@ -29,13 +30,12 @@ use Illuminate\Support\Facades\Log;
* [1] Resolve network config from order item → product → ipAddress template
* [2] for attempt 1..MAX_ATTEMPTS:
* [3] Pick a free IP with DB transaction + lock (reserveIp)
* [4] Pre-check: ping IP — if reachable → release and try next
* [5] Call assignIPLinux.ps1 / assignIPWindows.ps1 via SSH
* [6] On FAIL → release IP, try next
* [7] Call verifyIPLinux.ps1 / verifyIPWindows.ps1 via SSH
* [8] On FAIL → release IP, try next
* [9] SUCCESS → persistIp() → dispatch SendVmCredentialsEmailJob
* [10] All attempts exhausted → mark VM inactive (status=0)
* [4] Call assignIPLinux.ps1 / assignIPWindows.ps1 via SSH
* [5] On FAIL → release IP, try next
* [6] Call verifyIPLinux.ps1 / verifyIPWindows.ps1 via SSH
* [7] On FAIL → release IP, try next
* [8] SUCCESS → persistIp() → dispatch SendVmCredentialsEmailJob
* [9] All attempts exhausted → mark VM inactive (status=0)
*/
class AssignIpToGuestJob implements ShouldQueue
{
@@ -58,7 +58,7 @@ class AssignIpToGuestJob implements ShouldQueue
// ─────────────────────────────────────────────────────────────────────────
public function handle(VsphereHostSshService $ssh, vCenter $vCenterService): void
public function handle(VsphereHostSshService $ssh, vCenterService $vCenterService): void
{
Log::info('AssignIpToGuestJob: start', [
'module_vmware_id' => $this->moduleVmwareId,
@@ -118,16 +118,6 @@ class AssignIpToGuestJob implements ShouldQueue
$ip = $reservation->ip;
// [4] Pre-check: skip IPs that are already reachable (in use by another host)
if ($this->isIpReachable($ip)) {
Log::warning('AssignIpToGuestJob: IP reachable (likely in use), skipping', [
'ip' => $ip,
'attempt' => $attempt,
]);
$this->releaseIp($reservation);
continue;
}
// [5] Assign IP into VM guest OS via PS1 script
$assignOutput = $ssh->assignIp(
vmId: $this->vmId,
@@ -339,16 +329,6 @@ class AssignIpToGuestJob implements ShouldQueue
// Micro-helpers
// ─────────────────────────────────────────────────────────────────────────
/**
* Ping the IP from the Laravel host (1 packet, 1 s timeout).
* Returns true if reachable → the IP is already in use by something else.
*/
private function isIpReachable(string $ip): bool
{
exec(sprintf('ping -c 1 -W 1 %s 2>/dev/null', escapeshellarg($ip)), $output, $exitCode);
return $exitCode === 0;
}
/** PS1 scripts output exactly "SUCCESS" or "FAIL". */
private function isSuccess(string $output): bool
{