Files
portal-api/app/Jobs/VirtualMachine/Action/ResetVmPasswordJob.php
T
2025-08-24 22:41:15 +07:00

102 lines
3.3 KiB
PHP

<?php
namespace App\Jobs\VirtualMachine\Action;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Http\Services\vCenter;
use App\Mail\VmPasswordResetSuccess;
use App\Models\ModuleVmware;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class ResetVmPasswordJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $timeout = 180;
public function __construct(
public string $productId,
public string $oldPassword,
public string $newPassword,
public int $userId,
public string $email
) {}
public function handle(vCenter $serviceVCenter): void
{
$product = ModuleVmware::with('ipAddress.host.datacenter.vCenter','os.osGroup')
->where('vmware_id', $this->productId)
->where('customer_id', $this->userId)
->firstOrFail();
$osFamily = (string)($product->os->osGroup->name ?? '');
$isWindows = stripos($osFamily, 'windows') !== false;
if (!$isWindows) {
throw new \RuntimeException('Only Windows is supported by this reset job.');
}
$vmName = $product->ipAddress->vm_name
?? $product->name
?? $product->hostname
?? null;
if (!$vmName && preg_match('/^vm-\d+$/i', (string)$product->vmware_id)) {
$rawName = trim($serviceVCenter->runPsCommand("(Get-VM -Id '".addslashes($product->vmware_id)."').Name"));
if (($p = strpos($rawName, '[STDERR]')) !== false) {
$rawName = trim(substr($rawName, 0, $p));
}
$vmName = trim(preg_replace('/\s+/', ' ', $rawName));
}
if (!$vmName) {
throw new \RuntimeException('Cannot resolve VM Name on vCenter.');
}
$guestUser = 'Administrator';
$guestPassword = $this->oldPassword;
$result = $serviceVCenter->resetGuestPasswordViaPs1(
vmName: $vmName,
guestUser: $guestUser,
guestPassword: $guestPassword,
newPassword: $this->newPassword,
);
$product->update(['password' => encrypt($this->newPassword)]);
if ($result === 'Login_Fail' || $result === false || $result === null) {
throw new \RuntimeException('SSH runner login failed.');
}
if (is_string($result)) {
throw new \RuntimeException('Script returned non-JSON output: '.$result);
}
$row = $result;
if (isset($result[0])) {
$row = $result[0];
foreach ($result as $it) {
if (is_array($it) && (($it['vm'] ?? null) === $vmName)) { $row = $it; break; }
}
}
$status = strtolower($row['status'] ?? '');
if ($status !== 'ok') {
throw new \RuntimeException($row['message'] ?? 'Reset failed by script');
}
// Gửi mail thông báo
Mail::to($this->email)->send(
new VmPasswordResetSuccess(vmName: $vmName, newPassword: $this->newPassword)
);
Log::info('ResetVmPasswordJob: success', ['vm'=>$vmName]);
}
}