update change password
This commit is contained in:
+157
-18
@@ -15,7 +15,6 @@ use phpseclib3\Net\SSH2;
|
||||
|
||||
class vCenter
|
||||
{
|
||||
protected $process = null;
|
||||
public ?string $token = null;
|
||||
public string $apiUri = '10.10.10.6';
|
||||
private string $username = 'administrator@vsphere.local';
|
||||
@@ -23,7 +22,8 @@ class vCenter
|
||||
private int $diskCapacity = 1073741824;
|
||||
private int $memory = 1024;
|
||||
|
||||
protected string $os;
|
||||
private ?string $os = null;
|
||||
private SSH2|WinRMClient|null $process = null;
|
||||
|
||||
public function loginServer(\App\Models\Vcenter $vcenterModel): bool|string
|
||||
{
|
||||
@@ -325,6 +325,142 @@ class vCenter
|
||||
}
|
||||
}
|
||||
|
||||
// Login SSH
|
||||
public function loginSSH(): bool
|
||||
{
|
||||
$conn = $this->LoginAuth();
|
||||
|
||||
if ($conn) {
|
||||
Log::info("✅ Connected to vCenter via SSH successfully");
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::error("❌ Failed to connect to vCenter via SSH");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function runPsCommand(string $psCommand): string
|
||||
{
|
||||
$auth = $this->LoginAuth();
|
||||
if (!$auth)
|
||||
return "Login_Fail";
|
||||
|
||||
// gọi trực tiếp -Command, thu cả STDERR
|
||||
$action = 'powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass '
|
||||
. '-Command "' . str_replace('"', '\"', $psCommand) . '"';
|
||||
|
||||
try {
|
||||
$stream = ssh2_exec($auth, $action);
|
||||
if (!$stream)
|
||||
throw new \RuntimeException("ssh2_exec failed");
|
||||
$err = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
|
||||
stream_set_blocking($stream, true);
|
||||
stream_set_blocking($err, true);
|
||||
$out = stream_get_contents($stream) ?: '';
|
||||
$errOut = stream_get_contents($err) ?: '';
|
||||
return $out . ($errOut ? "\n[STDERR]\n" . $errOut : '');
|
||||
} catch (\Throwable $e) {
|
||||
return "Error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function CommandRSP(string $cmd)
|
||||
{
|
||||
$auth = $this->LoginAuth();
|
||||
if (!$auth)
|
||||
return "Login_Fail";
|
||||
|
||||
// Escape để dùng trong chuỗi single-quoted của PowerShell
|
||||
$esc = fn(string $v) => str_replace("'", "''", $v);
|
||||
|
||||
$server = $esc($this->apiUri ?? '');
|
||||
$user = $esc($this->username ?? '');
|
||||
$pass = $esc($this->password ?? '');
|
||||
|
||||
// Ghép script PowerShell hoàn chỉnh, chạy trong 1 scriptblock
|
||||
// Lưu ý: dùng placeholder rồi strtr để tránh lẫn dấu ngoặc
|
||||
$psTemplate = <<<'PS'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
$InformationPreference = 'SilentlyContinue'
|
||||
$WarningPreference = 'SilentlyContinue'
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
Import-Module VMware.PowerCLI -ErrorAction Stop
|
||||
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Scope Session -Confirm:$false | Out-Null
|
||||
Connect-VIServer -Server '<SERVER>' -User '<USER>' -Password '<PASS>' | Out-Null
|
||||
|
||||
# Thực thi lệnh công việc (đã được xây dựng sẵn, ví dụ: & 'C:\path\script.ps1' -Param 'Value' ... )
|
||||
& {
|
||||
<CMD>
|
||||
} | Out-String
|
||||
PS;
|
||||
|
||||
// Chèn dữ liệu
|
||||
$psScript = strtr($psTemplate, [
|
||||
'<SERVER>' => $server,
|
||||
'<USER>' => $user,
|
||||
'<PASS>' => $pass,
|
||||
'<CMD>' => $cmd, // ở đây $cmd KHÔNG cần ngoặc kép bao ngoài
|
||||
]);
|
||||
|
||||
// Encode UTF-16LE → Base64 cho -EncodedCommand
|
||||
$encoded = base64_encode(mb_convert_encoding($psScript, 'UTF-16LE', 'UTF-8'));
|
||||
|
||||
// Dùng -EncodedCommand để tránh mọi lỗi escape/quote
|
||||
$action = "powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand $encoded";
|
||||
|
||||
try {
|
||||
$stream = ssh2_exec($auth, $action);
|
||||
if (!$stream)
|
||||
return "ssh2_exec failed";
|
||||
$err = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
|
||||
stream_set_blocking($stream, true);
|
||||
stream_set_blocking($err, true);
|
||||
$out = stream_get_contents($stream) ?: '';
|
||||
$errOut = stream_get_contents($err) ?: '';
|
||||
return $out . ($errOut ? "\n[STDERR]\n" . $errOut : '');
|
||||
} catch (\Throwable $e) {
|
||||
return "Error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
public function resetGuestPasswordViaPs1(string $vmName, string $guestUser, string $guestPassword, string $newPassword, string $targetUser = 'Administrator'): array|string
|
||||
{
|
||||
// File ps1 chạy được ngoài PowerShell: bạn đã test ok
|
||||
$psFile = "C:\\CLISave\\AssignIP\\SetGuestPwd.ps1";
|
||||
|
||||
// Escape chuỗi cho PowerShell single-quoted
|
||||
$q = fn(string $v) => str_replace("'", "''", $v);
|
||||
|
||||
// Xây args kiểu: -Key 'Value'
|
||||
$args = " -VMName '" . $q($vmName) . "'";
|
||||
$args .= " -GuestUser '" . $q($guestUser) . "'";
|
||||
$args .= " -GuestPassword '" . $q($guestPassword) . "'";
|
||||
$args .= " -TargetUser '" . $q($targetUser) . "'";
|
||||
$args .= " -NewPassword '" . $q($newPassword) . "'";
|
||||
|
||||
// Gọi file trong cùng phiên PS đã Connect-VIServer (nhờ Command())
|
||||
// Thêm Out-String để ép JSON nằm trên STDOUT gọn
|
||||
$cmd = "& '$psFile'$args | Out-String";
|
||||
|
||||
$raw = $this->CommandRSP($cmd); // <-- dùng lại Command() của bạn
|
||||
if ($raw === 'Login_Fail' || $raw === false || $raw === null) {
|
||||
return "Login_Fail";
|
||||
}
|
||||
|
||||
// Thử parse JSON (có thể lẫn banner/log)
|
||||
$trim = trim($raw);
|
||||
$data = json_decode($trim, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
if (preg_match('/(\{.*\}|\[.*\])/s', $trim, $m)) {
|
||||
$data = json_decode($m[1], true);
|
||||
}
|
||||
}
|
||||
|
||||
return $data ?: $raw; // nếu chưa parse được, trả raw để debug
|
||||
}
|
||||
|
||||
private function getAllNetwork()
|
||||
{
|
||||
$check = $this->checkApiExits();
|
||||
@@ -457,7 +593,7 @@ class vCenter
|
||||
|
||||
try {
|
||||
Log::info('Bắt đầu clone VM với timeout 300 giây', ['template' => $template, 'target_name' => $body['spec']['name']]);
|
||||
|
||||
|
||||
$response = Http::withoutVerifying()
|
||||
->timeout(300) // Tăng timeout lên 5 phút cho quá trình clone
|
||||
->connectTimeout(30) // Giữ connect timeout ngắn để phát hiện lỗi kết nối sớm
|
||||
@@ -1854,8 +1990,11 @@ class vCenter
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function change_password_linux(array $data = ['ip' => '103.42.58.37', 'user' => 'root', 'password' => 'TGS@123', 'new_password' => '']): bool
|
||||
/*
|
||||
* ip = 103.42.58.37
|
||||
* pwd = TGS@123
|
||||
*/
|
||||
public function change_password_linux(array $data = ['ip' => '10.10.10.173', 'user' => 'admin', 'password' => 'TGS@123', 'new_password' => '']): bool
|
||||
{
|
||||
try {
|
||||
// Kiểm tra mật khẩu mới
|
||||
@@ -2139,14 +2278,14 @@ class vCenter
|
||||
$dns = '8.8.8.8';
|
||||
$vmware_name = '';
|
||||
$vCenter = null;
|
||||
|
||||
|
||||
// Check if it's ModuleVmware (new structure)
|
||||
if ($product && isset($product->ipAddress) && $product->ipAddress) {
|
||||
Log::info('✅ Using ModuleVmware structure for assignIPWindows', [
|
||||
'module_vmware_id' => $product->id,
|
||||
'vmware_id' => $vmware_id
|
||||
]);
|
||||
|
||||
|
||||
// Extract from ModuleVmware->ipAddress relationship
|
||||
$ipAddress = $product->ipAddress->ip ?? null;
|
||||
$gateway = $product->ipAddress->gateway ?? null;
|
||||
@@ -2154,13 +2293,13 @@ class vCenter
|
||||
$dns = $product->ipAddress->dns ?? '8.8.8.8';
|
||||
$vmware_name = $product->name ?? $vmware_id;
|
||||
$vCenter = $product->ipAddress->host->datacenter->vCenter ?? null;
|
||||
|
||||
|
||||
} elseif ($product && isset($product->IpAddress) && $product->IpAddress) {
|
||||
Log::info('✅ Using old Product structure for assignIPWindows', [
|
||||
'product_id' => $product->id,
|
||||
'vmware_id' => $vmware_id
|
||||
]);
|
||||
|
||||
|
||||
// Extract from old Product->IpAddress relationship
|
||||
$ipAddress = $product->IpAddress->ip ?? null;
|
||||
$gateway = $product->IpAddress->gateway ?? null;
|
||||
@@ -2169,7 +2308,7 @@ class vCenter
|
||||
$vmware_name = $product->name ?? $vmware_id;
|
||||
$vCenter = $product->IpAddress->Host->Datacenter->vCenter ?? null;
|
||||
}
|
||||
|
||||
|
||||
// Validate required data
|
||||
if (!$ipAddress || !$gateway || !$vCenter) {
|
||||
Log::error('❌ assignIPWindows: Missing required data', [
|
||||
@@ -2186,10 +2325,10 @@ class vCenter
|
||||
}
|
||||
|
||||
$this->SetConfig($vCenter);
|
||||
|
||||
|
||||
// Convert netmask to prefix length (e.g., 255.255.255.0 = 24)
|
||||
$maskBits = $this->convertNetmaskToPrefixLength($netmask);
|
||||
|
||||
|
||||
Log::channel('Custom')->info("===================================================================");
|
||||
Log::channel('Custom')->info("Assign IP to Windows VM - $vmware_name");
|
||||
Log::channel('Custom')->info("IP: $ipAddress, Gateway: $gateway, DNS: $dns, MaskBits: $maskBits");
|
||||
@@ -2197,14 +2336,14 @@ class vCenter
|
||||
|
||||
// Create PowerShell command with dynamic values
|
||||
$Command = "\$vmName = '$vmware_name'; \$IP = '$ipAddress'; \$MaskBits = $maskBits; \$Gateway = '$gateway'; \$DNS = '$dns'; cd /; C:\CLISave\AssignIP\assignIPWindows.ps1;";
|
||||
|
||||
|
||||
Log::channel('Custom')->info("Executing Command: $Command");
|
||||
|
||||
|
||||
$output = $this->Command($Command);
|
||||
|
||||
|
||||
Log::channel('Custom')->info("Script output: " . $output);
|
||||
Log::channel('Custom')->info("===================================================================");
|
||||
|
||||
|
||||
// Check if execution was successful
|
||||
if (strpos($output, '🎉') !== false || strpos($output, 'successfully') !== false) {
|
||||
return [
|
||||
@@ -2219,7 +2358,7 @@ class vCenter
|
||||
'output' => $output
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::channel('Custom')->error("Exception in assignIPWindows: " . $e->getMessage());
|
||||
return [
|
||||
@@ -2261,7 +2400,7 @@ class vCenter
|
||||
'255.128.0.0' => 9,
|
||||
'255.0.0.0' => 8
|
||||
];
|
||||
|
||||
|
||||
return $netmaskMap[$netmask] ?? 24; // Default to /24 if not found
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user