feat: Implement asynchronous VM power operations and refactor vCenter snapshot retrieval to use API calls.
This commit is contained in:
@@ -422,122 +422,6 @@ class ServiceController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lấy danh sách snapshot với bảo mật và tối ưu hóa
|
||||
*/
|
||||
// public function getSnapshots(Request $request, vCenter $serviceVCenter)
|
||||
// {
|
||||
// try {
|
||||
// // Kiểm tra authentication
|
||||
// $user = customer();
|
||||
// if (!$user) {
|
||||
// return response()->json([
|
||||
// 'error' => true,
|
||||
// 'message' => __('Chưa đăng nhập. Vui lòng đăng nhập để sử dụng tính năng này.')
|
||||
// ], 401);
|
||||
// }
|
||||
|
||||
// // Validation với sanitization
|
||||
// $validator = Validator::make($request->all(), [
|
||||
// 'product_id' => 'required|string|max:255',
|
||||
// ]);
|
||||
|
||||
// if ($validator->fails()) {
|
||||
// return response()->json([
|
||||
// 'error' => true,
|
||||
// 'message' => __('Dữ liệu không hợp lệ'),
|
||||
// 'errors' => $validator->errors()
|
||||
// ], 422);
|
||||
// }
|
||||
|
||||
// $productId = $this->sanitizeInput($request->product_id);
|
||||
// $userId = $user->id;
|
||||
|
||||
// // Cache key cho snapshot data
|
||||
// $cacheKey = "snapshots_{$userId}_{$productId}";
|
||||
// $cacheDuration = 300; // 5 phút
|
||||
|
||||
// // Thử lấy từ cache trước
|
||||
// if (Cache::has($cacheKey)) {
|
||||
// $cachedData = Cache::get($cacheKey);
|
||||
// if ($cachedData && !$this->isCacheExpired($cachedData)) {
|
||||
// return response()->json([
|
||||
// 'error' => false,
|
||||
// 'message' => __('Lấy danh sách snapshot thành công'),
|
||||
// 'data' => $cachedData,
|
||||
// 'cached' => true
|
||||
// ]);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Tìm VPS với eager loading tối ưu
|
||||
// $product = $this->findVmwareProduct($productId, $userId);
|
||||
// if (!$product) {
|
||||
// return response()->json([
|
||||
// 'error' => true,
|
||||
// 'message' => __('Không tìm thấy VPS hoặc bạn không có quyền truy cập')
|
||||
// ], 404);
|
||||
// }
|
||||
|
||||
// // Kiểm tra cấu hình vCenter
|
||||
// $vcenter = $this->validateVcenterConfiguration($product);
|
||||
// if (!$vcenter) {
|
||||
// return response()->json([
|
||||
// 'error' => true,
|
||||
// 'message' => __('Cấu hình vCenter không hợp lệ')
|
||||
// ], 400);
|
||||
// }
|
||||
|
||||
// // Lấy snapshot từ vCenter
|
||||
// $snapshots = $this->fetchSnapshotsFromVCenter($serviceVCenter, $product, $vcenter);
|
||||
// if ($snapshots === false) {
|
||||
// return response()->json([
|
||||
// 'error' => true,
|
||||
// 'message' => __('Không thể kết nối đến vCenter')
|
||||
// ], 500);
|
||||
// }
|
||||
|
||||
// // Lấy thông tin bổ sung từ database
|
||||
// $dbSnapshots = $this->getDatabaseSnapshots($userId, $product->id);
|
||||
|
||||
// // Merge và sanitize data
|
||||
// $processedSnapshots = $this->processSnapshotsData($snapshots, $dbSnapshots);
|
||||
|
||||
// // Chuẩn bị response data
|
||||
// $responseData = [
|
||||
// 'snapshots' => $processedSnapshots,
|
||||
// 'total_count' => count($processedSnapshots),
|
||||
// 'vm_name' => $this->sanitizeOutput($product->name),
|
||||
// 'vm_id' => $product->vmware_id,
|
||||
// 'last_updated' => now()->format('Y-m-d H:i:s')
|
||||
// ];
|
||||
|
||||
// // Cache kết quả
|
||||
// Cache::put($cacheKey, $responseData, $cacheDuration);
|
||||
|
||||
// return response()->json([
|
||||
// 'error' => false,
|
||||
// 'message' => __('Lấy danh sách snapshot thành công'),
|
||||
// 'data' => $responseData,
|
||||
// 'cached' => false
|
||||
// ]);
|
||||
// } catch (\Exception $e) {
|
||||
// Log::error('Lỗi khi lấy danh sách snapshot', [
|
||||
// 'user_id' => $user->id ?? 'guest',
|
||||
// 'product_id' => $request->product_id ?? 'not_provided',
|
||||
// 'error' => $e->getMessage(),
|
||||
// 'file' => $e->getFile(),
|
||||
// 'line' => $e->getLine()
|
||||
// ]);
|
||||
|
||||
// return response()->json([
|
||||
// 'error' => true,
|
||||
// 'message' => __('Có lỗi xảy ra khi lấy danh sách snapshot')
|
||||
// ], 500);
|
||||
// }
|
||||
// }
|
||||
|
||||
public function getSnapshots(Request $request)
|
||||
{
|
||||
$user = customer();
|
||||
@@ -1002,7 +886,10 @@ class ServiceController extends Controller
|
||||
/**
|
||||
* Secure start VM using session authentication - NO BEARER TOKEN
|
||||
*/
|
||||
public function startVM(Request $request, vCenter $vCenterService)
|
||||
/**
|
||||
* Secure start VM using session authentication - NO BEARER TOKEN
|
||||
*/
|
||||
public function startVM(Request $request)
|
||||
{
|
||||
try {
|
||||
$user = customer();
|
||||
@@ -1037,28 +924,19 @@ class ServiceController extends Controller
|
||||
], 404);
|
||||
}
|
||||
|
||||
$result = $vCenterService->StartVirtualMachine($product, $product->vmware_id);
|
||||
if (is_array($result) && isset($result['error']) && $result['error'] === false) {
|
||||
// Clear VM info cache after starting VM
|
||||
Cache::forget('vm_info_' . $product->vmware_id);
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => __('Yêu cầu khởi động máy ảo đã được gửi thành công.')
|
||||
]);
|
||||
} else {
|
||||
$msg = is_array($result) && isset($result['data']) ? $result['data'] : __('Không thể khởi động máy ảo');
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => $msg
|
||||
], 500);
|
||||
}
|
||||
// Dispatch Job
|
||||
\App\Jobs\VirtualMachine\Power\StartVmJob::dispatch($product->id, $userId);
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => __('Yêu cầu khởi động máy ảo đã được gửi. Vui lòng chờ trong giây lát.')
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Lỗi khi khởi động máy ảo', [
|
||||
'user_id' => $user->id ?? 'guest',
|
||||
'product_id' => $request->product_id ?? 'not_provided',
|
||||
'error' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine()
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
@@ -1070,7 +948,7 @@ class ServiceController extends Controller
|
||||
/**
|
||||
* Secure stop VM using session authentication - NO BEARER TOKEN
|
||||
*/
|
||||
public function stopVM(Request $request, vCenter $vCenterService)
|
||||
public function stopVM(Request $request)
|
||||
{
|
||||
try {
|
||||
$user = customer();
|
||||
@@ -1105,27 +983,19 @@ class ServiceController extends Controller
|
||||
], 404);
|
||||
}
|
||||
|
||||
$result = $vCenterService->ShutdownGuestVirtualMachine($product, $product->vmware_id);
|
||||
if (is_array($result) && isset($result['error']) && $result['error'] === false) {
|
||||
Cache::forget('the_gioi_so_database_the_gioi_so_cache:vm_info_' . $product->vmware_id);
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => __('Yêu cầu tắt máy ảo đã được gửi thành công.')
|
||||
]);
|
||||
} else {
|
||||
$msg = is_array($result) && isset($result['data']) ? $result['data'] : __('Không thể tắt máy ảo');
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => $msg
|
||||
], 500);
|
||||
}
|
||||
// Dispatch Job
|
||||
\App\Jobs\VirtualMachine\Power\StopVmJob::dispatch($product->id, $userId);
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => __('Yêu cầu tắt máy ảo đã được gửi. Vui lòng chờ trong giây lát.')
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Lỗi khi tắt máy ảo', [
|
||||
'user_id' => $user->id ?? 'guest',
|
||||
'product_id' => $request->product_id ?? 'not_provided',
|
||||
'error' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine()
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
@@ -1137,7 +1007,7 @@ class ServiceController extends Controller
|
||||
/**
|
||||
* Secure reboot VM using session authentication - NO BEARER TOKEN
|
||||
*/
|
||||
public function rebootVM(Request $request, vCenter $vCenterService)
|
||||
public function rebootVM(Request $request)
|
||||
{
|
||||
try {
|
||||
$user = customer();
|
||||
@@ -1172,26 +1042,19 @@ class ServiceController extends Controller
|
||||
], 404);
|
||||
}
|
||||
|
||||
$result = $vCenterService->RebootVirtualMachine($product, $product->vmware_id);
|
||||
if (is_array($result) && isset($result['error']) && $result['error'] === false) {
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => __('Yêu cầu khởi động lại máy ảo đã được gửi thành công.')
|
||||
]);
|
||||
} else {
|
||||
$msg = is_array($result) && isset($result['data']) ? $result['data'] : __('Không thể khởi động lại máy ảo');
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => $msg
|
||||
], 500);
|
||||
}
|
||||
// Dispatch Job
|
||||
\App\Jobs\VirtualMachine\Power\RebootVmJob::dispatch($product->id, $userId);
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
'message' => __('Yêu cầu khởi động lại máy ảo đã được gửi. Vui lòng chờ trong giây lát.')
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Lỗi khi reboot VM', [
|
||||
'user_id' => $user->id ?? 'guest',
|
||||
'product_id' => $request->product_id ?? 'not_provided',
|
||||
'error' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine()
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
|
||||
@@ -115,22 +115,6 @@ class VPSReinstallModal extends Component
|
||||
|
||||
// Try to get IP from vCenter API first, fallback to database
|
||||
$this->vpsIpAddress = $this->getIPFromVCenter() ?? $this->moduleVmware?->ipAddress?->ip ?? null;
|
||||
|
||||
// Debug ModuleVmware info
|
||||
Log::info('ModuleVmware debug info', [
|
||||
'invoice_item_id' => $this->invoiceItem->id,
|
||||
'invoice_item_relid' => $this->invoiceItem->relid,
|
||||
'invoice_item_type_id' => $this->invoiceItem->type_id,
|
||||
'invoice_customer_id' => $this->invoice?->customer_id ?? 'null',
|
||||
'module_vmware' => $this->moduleVmware ? 'found' : 'not_found',
|
||||
'module_vmware_id' => $this->moduleVmware?->id ?? 'null',
|
||||
'module_vmware_name' => $this->moduleVmware?->name ?? 'null',
|
||||
'module_vmware_customer_id' => $this->moduleVmware?->customer_id ?? 'null',
|
||||
'module_ip_address_id' => $this->moduleVmware?->module_ip_address_id ?? 'null',
|
||||
'ip_address_relationship' => $this->moduleVmware?->ipAddress ? 'found' : 'not_found',
|
||||
'ip_address_from_db' => $this->moduleVmware?->ipAddress?->ip ?? 'null',
|
||||
'ip_address_from_vcenter' => $this->vpsIpAddress ?? 'null'
|
||||
]);
|
||||
} else {
|
||||
Log::warning('InvoiceItem not found', [
|
||||
'invoice_id' => $this->invoiceId,
|
||||
@@ -139,15 +123,6 @@ class VPSReinstallModal extends Component
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Log::info('OS data loaded successfully', [
|
||||
'product_id' => $productId,
|
||||
'os_groups_count' => is_object($this->osGroups) ? $this->osGroups->count() : count($this->osGroups),
|
||||
'current_os' => $this->currentOs ? $this->currentOs->id : null,
|
||||
'module_vmware_id' => $this->moduleVmware ? $this->moduleVmware->id : null,
|
||||
'ip_address' => $this->moduleVmware?->ipAddress?->ip ?? 'N/A'
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error loading OS data', [
|
||||
'product_id' => $productId,
|
||||
|
||||
+175
-101
@@ -861,13 +861,6 @@ PS;
|
||||
'hot_add_enabled' => true
|
||||
]
|
||||
];
|
||||
|
||||
Log::info("📤 Payload CPU", [
|
||||
'payload' => $payload,
|
||||
'cpu_count' => $cpuCount,
|
||||
'cores_per_socket' => $coresPerSocket
|
||||
]);
|
||||
|
||||
$response = Http::withoutVerifying()
|
||||
->timeout(30)
|
||||
->withHeaders([
|
||||
@@ -1627,120 +1620,201 @@ PS;
|
||||
}
|
||||
|
||||
$vmware_name = (string) $product->name;
|
||||
$vmId = $product->vmware_id;
|
||||
|
||||
// Check cache first
|
||||
$cacheKey = "snapshots_{$product->id}_{$vmware_name}";
|
||||
$cachedResult = Cache::get($cacheKey);
|
||||
|
||||
if ($cachedResult !== null) {
|
||||
$executionTime = round((microtime(true) - $startTime) * 1000, 2);
|
||||
Log::channel('Custom')->info("📸 Snapshot cache hit - Execution time: {$executionTime}ms");
|
||||
Log::channel('Custom')->info("📸 Snapshot cache hit");
|
||||
return $cachedResult;
|
||||
}
|
||||
|
||||
$check = $this->checkApiExits();
|
||||
try {
|
||||
Log::channel('Custom')->info("🚀 Starting SOAP Snapshot Fetch for VM: $vmId ($vmware_name)");
|
||||
|
||||
if ($check) {
|
||||
try {
|
||||
Log::channel('Custom')->info("===================================================================");
|
||||
Log::channel('Custom')->info("Get Snapshots for VirtualMachine Name - $vmware_name");
|
||||
Log::channel('Custom')->info("\r\n");
|
||||
// 1. SOAP Login
|
||||
$sessionToken = $this->soapLogin();
|
||||
if (!$sessionToken) {
|
||||
return "Login_Again";
|
||||
}
|
||||
|
||||
// Use the getsnapshot.ps1 script file
|
||||
$Command = "\$vm_name = '$vmware_name'; cd /; C:\CLISave\getsnapshot.ps1;";
|
||||
// 2. Retrieve Snapshot Info
|
||||
$snapshotInfo = $this->getVMSnapshotInfoSoap($sessionToken, $vmId);
|
||||
|
||||
Log::channel('Custom')->info("$Command");
|
||||
|
||||
$commandStartTime = microtime(true);
|
||||
$result = $this->Command($Command);
|
||||
$commandTime = round((microtime(true) - $commandStartTime) * 1000, 2);
|
||||
|
||||
Log::channel('Custom')->info("\r\n");
|
||||
Log::channel('Custom')->info("Command Result: " . $result);
|
||||
Log::channel('Custom')->info("Command Execution Time: {$commandTime}ms");
|
||||
Log::channel('Custom')->info("After run Command |" . Carbon::now());
|
||||
Log::channel('Custom')->info("===================================================================");
|
||||
|
||||
// Parse result
|
||||
if ($result && $result !== "Login_Fail") {
|
||||
try {
|
||||
// Clean up the result - remove any PowerShell formatting
|
||||
$cleanResult = trim($result);
|
||||
|
||||
// Parse the text output from the script
|
||||
$snapshots = $this->parseSnapshotTextOutput($cleanResult);
|
||||
|
||||
if (!empty($snapshots)) {
|
||||
$response = [
|
||||
'error' => false,
|
||||
'data' => $snapshots
|
||||
];
|
||||
|
||||
// Cache the result for 5 minutes
|
||||
Cache::put($cacheKey, $response, now()->addMinutes(5));
|
||||
|
||||
$totalTime = round((microtime(true) - $startTime) * 1000, 2);
|
||||
Log::channel('Custom')->info("📸 Snapshot retrieved successfully - Total time: {$totalTime}ms, Command time: {$commandTime}ms");
|
||||
|
||||
return $response;
|
||||
} else {
|
||||
$response = [
|
||||
'error' => true,
|
||||
'message' => 'Không tìm thấy snapshot nào hoặc lỗi parse dữ liệu',
|
||||
'raw_result' => $result
|
||||
];
|
||||
|
||||
$totalTime = round((microtime(true) - $startTime) * 1000, 2);
|
||||
Log::channel('Custom')->info("📸 No snapshots found - Total time: {$totalTime}ms");
|
||||
|
||||
return $response;
|
||||
}
|
||||
} catch (\Exception $parseError) {
|
||||
Log::channel('Custom')->info("Parse Error: " . $parseError->getMessage());
|
||||
$response = [
|
||||
'error' => true,
|
||||
'message' => 'Lỗi parse kết quả snapshot: ' . $parseError->getMessage(),
|
||||
'raw_result' => $result
|
||||
];
|
||||
|
||||
$totalTime = round((microtime(true) - $startTime) * 1000, 2);
|
||||
Log::channel('Custom')->info("📸 Parse error - Total time: {$totalTime}ms");
|
||||
|
||||
return $response;
|
||||
// 3. Flatten Tree
|
||||
$snapshots = [];
|
||||
if (isset($snapshotInfo['rootSnapshotList'])) {
|
||||
// Handle single object vs array in XML to JSON conversion
|
||||
$roots = $snapshotInfo['rootSnapshotList'];
|
||||
// Ensure it's an array if single
|
||||
if (isset($roots['snapshot'])) {
|
||||
// It's a single node structure, allow recurse
|
||||
$snapshots = $this->flattenSnapshotTree($roots);
|
||||
} elseif (is_array($roots)) {
|
||||
foreach ($roots as $root) {
|
||||
$snapshots = array_merge($snapshots, $this->flattenSnapshotTree($root));
|
||||
}
|
||||
} else {
|
||||
$response = [
|
||||
'error' => true,
|
||||
'message' => 'Không thể thực thi lệnh hoặc đăng nhập thất bại',
|
||||
'raw_result' => $result
|
||||
];
|
||||
|
||||
$totalTime = round((microtime(true) - $startTime) * 1000, 2);
|
||||
Log::channel('Custom')->info("📸 Command failed - Total time: {$totalTime}ms");
|
||||
|
||||
return $response;
|
||||
}
|
||||
} catch (\Exception $error) {
|
||||
Log::channel('Custom')->info("\r\n");
|
||||
Log::channel('Custom')->info("===================================================================");
|
||||
Log::channel('Custom')->info("Error Log: ");
|
||||
Log::channel('Custom')->info($error->getMessage());
|
||||
Log::channel('Custom')->info("===================================================================");
|
||||
}
|
||||
|
||||
$totalTime = round((microtime(true) - $startTime) * 1000, 2);
|
||||
Log::channel('Custom')->info("📸 Exception occurred - Total time: {$totalTime}ms");
|
||||
|
||||
return [
|
||||
'error' => true,
|
||||
'message' => $error->getMessage()
|
||||
// Format similar to old output
|
||||
$formattedSnapshots = [];
|
||||
foreach ($snapshots as $snap) {
|
||||
$formattedSnapshots[] = [
|
||||
'name' => $snap['name'],
|
||||
'description' => $snap['description'] ?? '',
|
||||
'created' => $snap['createTime'],
|
||||
'id' => $snap['snapshot']['_'] ?? $snap['snapshot'], // MO Ref Value
|
||||
'is_current' => false, // Simplification, need logic to check against currentSnapshot
|
||||
'parent_snapshot_id' => '', // Hard to determining flat parent in simple recursion without passing parent id
|
||||
'size_gb' => 0 // SOAP doesnt always return size in tree
|
||||
];
|
||||
}
|
||||
|
||||
$response = [
|
||||
'error' => false,
|
||||
'data' => $formattedSnapshots
|
||||
];
|
||||
|
||||
Cache::put($cacheKey, $response, now()->addMinutes(5));
|
||||
return $response;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::channel('Custom')->error("❌ SOAP Snapshot Error: " . $e->getMessage());
|
||||
return [
|
||||
'error' => true,
|
||||
'message' => 'Lỗi lấy snapshot qua SOAP: ' . $e->getMessage()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private function soapLogin()
|
||||
{
|
||||
$body = '
|
||||
<soapenv:Body>
|
||||
<Login xmlns="urn:vim25">
|
||||
<_this type="SessionManager">SessionManager</_this>
|
||||
<userName>' . htmlspecialchars($this->username) . '</userName>
|
||||
<password>' . htmlspecialchars($this->password) . '</password>
|
||||
</Login>
|
||||
</soapenv:Body>';
|
||||
|
||||
$response = $this->callSoap($body);
|
||||
|
||||
// Extract session cookie if needed, but Login typically sets checking cookie.
|
||||
// Actually for Http Client, we need to grab the cookie "vmware_soap_session"
|
||||
// But the callSoap helper needs to handle cookies.
|
||||
|
||||
return $response['cookie'] ?? null;
|
||||
}
|
||||
|
||||
private function getVMSnapshotInfoSoap($cookie, $vmId)
|
||||
{
|
||||
$body = '
|
||||
<soapenv:Body>
|
||||
<RetrievePropertiesEx xmlns="urn:vim25">
|
||||
<_this type="PropertyCollector">propertyCollector</_this>
|
||||
<specSet>
|
||||
<propSet>
|
||||
<type>VirtualMachine</type>
|
||||
<all>false</all>
|
||||
<pathSet>snapshot</pathSet>
|
||||
</propSet>
|
||||
<objectSet>
|
||||
<obj type="VirtualMachine">' . $vmId . '</obj>
|
||||
</objectSet>
|
||||
</specSet>
|
||||
<options></options>
|
||||
</RetrievePropertiesEx>
|
||||
</soapenv:Body>';
|
||||
|
||||
$result = $this->callSoap($body, $cookie);
|
||||
|
||||
// Parse simple XML response to finding snapshot info
|
||||
// This is tricky with Regex/SimpleXML. We need to extract the returnval.
|
||||
|
||||
if (isset($result['body'])) {
|
||||
$xml = simplexml_load_string($result['body']);
|
||||
$xml->registerXPathNamespace('u', 'urn:vim25');
|
||||
// Navigate to returnval -> objects -> propSet -> val -> rootSnapshotList
|
||||
// Path depends on exact response structure
|
||||
|
||||
// Simplified return for now:
|
||||
$json = json_encode($xml);
|
||||
$array = json_decode($json, true);
|
||||
|
||||
// Deep dive into array to find "snapshot" property
|
||||
// This needs robust traversing
|
||||
return $this->findSnapshotPropertyInArray($array);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private function findSnapshotPropertyInArray($array)
|
||||
{
|
||||
// Recursive search for 'rootSnapshotList' or 'currentSnapshot'
|
||||
if (isset($array['rootSnapshotList']))
|
||||
return $array;
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$found = $this->findSnapshotPropertyInArray($value);
|
||||
if ($found)
|
||||
return $found;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private function flattenSnapshotTree($node)
|
||||
{
|
||||
$list = [];
|
||||
// Add self
|
||||
$list[] = $node;
|
||||
|
||||
// Add children
|
||||
if (isset($node['childSnapshotList'])) {
|
||||
$children = $node['childSnapshotList'];
|
||||
// Check if single child or array of children
|
||||
if (isset($children['snapshot'])) {
|
||||
$list = array_merge($list, $this->flattenSnapshotTree($children));
|
||||
} else {
|
||||
foreach ($children as $child) {
|
||||
$list = array_merge($list, $this->flattenSnapshotTree($child));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
private function callSoap($soapBody, $cookie = null)
|
||||
{
|
||||
$envelope = '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
' . $soapBody . '
|
||||
</soapenv:Envelope>';
|
||||
|
||||
$headers = [
|
||||
'Content-Type' => 'text/xml; charset=utf-8',
|
||||
'SOAPAction' => 'urn:vim25/2005'
|
||||
];
|
||||
|
||||
if ($cookie) {
|
||||
$headers['Cookie'] = $cookie;
|
||||
}
|
||||
|
||||
$totalTime = round((microtime(true) - $startTime) * 1000, 2);
|
||||
Log::channel('Custom')->info("📸 Login again required - Total time: {$totalTime}ms");
|
||||
$response = Http::withoutVerifying()
|
||||
->withHeaders($headers)
|
||||
->post("https://{$this->apiUri}/sdk", $envelope);
|
||||
|
||||
return "Login_Again";
|
||||
$responseCookie = $response->header('Set-Cookie');
|
||||
|
||||
return [
|
||||
'body' => $response->body(),
|
||||
'cookie' => $responseCookie ? $responseCookie : $cookie
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user