1547 lines
74 KiB
PHP
1547 lines
74 KiB
PHP
<?php
|
|
|
|
use App\Http\Controllers\Api\Client\ClientController;
|
|
use App\Http\Controllers\rest\ModuleController;
|
|
use App\Http\Services\Media;
|
|
use App\Http\Services\vCenter as ServiceVCenter;
|
|
use App\Jobs\Hosting\CreateHostingJobs;
|
|
use App\Jobs\VirtualMachine\Create\CreateVMJobs;
|
|
use App\Jobs\VirtualMachine\Upgrade\UpgradeVirtualMachine;
|
|
use App\Models\Addon;
|
|
use App\Models\Customer;
|
|
use App\Models\File;
|
|
use App\Models\Hosting;
|
|
use App\Models\Invoice;
|
|
use App\Models\InvoiceItem;
|
|
use App\Models\ModuleDatacenter;
|
|
use App\Models\ModuleHost;
|
|
use App\Models\ModuleHosting;
|
|
use App\Models\ModuleHostingServer;
|
|
use App\Models\ModuleIpAddress;
|
|
use App\Models\ModuleSnapshot;
|
|
use App\Models\ModuleVmware;
|
|
use App\Models\Os;
|
|
use App\Models\OsGroup;
|
|
use App\Models\Type;
|
|
use App\Models\vCenter;
|
|
use App\Models\VPS;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Illuminate\Support\Str;
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| API Routes
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Here is where you can register API routes for your application. These
|
|
| routes are loaded by the RouteServiceProvider within a group which
|
|
| is assigned the "api" middleware group. Enjoy building your API!
|
|
|
|
|
*/
|
|
|
|
Route::prefix('v1')
|
|
/* Api for Admin */
|
|
->group(function () {
|
|
Route::prefix('system')->middleware(['api.auth'])->group(function () {
|
|
Route::controller(ModuleController::class)->group(function () {
|
|
Route::get('get-list-vcenter', 'getVCenter')->name('api.getVCenter');
|
|
Route::get('get-list-datacenter', 'getDatacenter')->name('api.getDatacenter');
|
|
Route::get('get-list-host', 'getHost')->name('api.getHost');
|
|
Route::get('get-list-datastore', 'getDatastore')->name('api.getDatastore');
|
|
Route::get('get-list-network', 'getNetwork')->name('api.getNetwork');
|
|
Route::get('get-list-ipaddress', 'getIpAddress')->name('api.getIPAddress');
|
|
Route::get('get-list-version-os', 'getOsServerVersion')->name('api.getVersion');
|
|
Route::get('get-list-os-group', 'getOsGroup')->name('api.getOsGroup');
|
|
});
|
|
|
|
Route::post('rebuild-vps', [\App\Http\Controllers\Api\VpsActionController::class, 'rebuildVps'])
|
|
->name('api.system.rebuildVps');
|
|
|
|
Route::get('get-list-product', function () {
|
|
$type_id = \request()->get('type');
|
|
if (!$type_id) {
|
|
return response()->json(['error' => true, 'message' => 'Please choose Type']);
|
|
}
|
|
|
|
if ($type_id === 1 || $type_id === 2) {
|
|
return response()->json(['error' => true, 'message' => 'Not Found']);
|
|
}
|
|
|
|
$model = null;
|
|
|
|
switch ($type_id) {
|
|
|
|
case 3:
|
|
$model = Hosting::select('id', 'name', 'price', 'price_sale')->get();
|
|
break;
|
|
case 4:
|
|
|
|
$model = VPS::select('id', 'name', 'price', 'price_sale', 'module_host_id')->get();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!$model) {
|
|
return response()->json(['error' => true, 'message' => 'Not Found']);
|
|
}
|
|
|
|
return response()->json(['error' => false, 'data' => $model->all()]);
|
|
})->name('api.getProduct');
|
|
Route::get('get-list-product-type', function () {
|
|
$type = Type::select('id', 'name')->get();
|
|
return response()->json(['error' => false, 'data' => $type->all()]);
|
|
})->name('api.getProductType');
|
|
|
|
Route::get('get-ticket-console', function (Request $request, ServiceVCenter $serviceVCenter) {
|
|
$product_id = $request->get('product');
|
|
if (!$product_id) {
|
|
return response()->json(['error' => true, 'message' => "Please choose product"]);
|
|
}
|
|
$product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')->find($product_id);
|
|
if (!$product) {
|
|
return response()->json(['error' => true, 'message' => "Can't find product"]);
|
|
}
|
|
|
|
$vcenter = null;
|
|
if ($product->ipAddress && $product->ipAddress->host && $product->ipAddress->host->datacenter && $product->ipAddress->host->datacenter->vCenter) {
|
|
$vcenter = $product->ipAddress->host->datacenter->vCenter;
|
|
}
|
|
|
|
if (!$vcenter) {
|
|
return response()->json(['error' => true, 'message' => "Can't find vCenter information"]);
|
|
}
|
|
|
|
// Đăng nhập vCenter trước khi lấy ticket
|
|
if (!$serviceVCenter->loginServer($vcenter)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập vào vCenter'
|
|
]);
|
|
}
|
|
|
|
$ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id);
|
|
|
|
// Nếu login hết hạn, thử login lại 1 lần nữa
|
|
if ($ConsoleTicket === 'Login_Again') {
|
|
if ($serviceVCenter->loginServer($vcenter)) {
|
|
$ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id);
|
|
} else {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập lại vào vCenter'
|
|
]);
|
|
}
|
|
}
|
|
|
|
// Nếu vẫn lỗi, trả về lỗi rõ ràng
|
|
if (is_string($ConsoleTicket)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => "Failed to get console ticket: $ConsoleTicket"
|
|
]);
|
|
}
|
|
|
|
if ($ConsoleTicket['error']) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => $ConsoleTicket['data']
|
|
]);
|
|
}
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => $ConsoleTicket['data'],
|
|
'host' => $vcenter->host,
|
|
'vmware-api-session-id' => $serviceVCenter->token
|
|
])->cookie('vmware-api-session-id', $serviceVCenter->token, 60, '/', null, false, false);
|
|
})->name('api.GetConsoleTicket');
|
|
|
|
Route::get('get-version-os', function () {
|
|
$group_id = \request()->get('group');
|
|
if (!$group_id) {
|
|
return response()->json(['error' => true, 'message' => 'Please choose Host']);
|
|
}
|
|
$group_os = OsGroup::find($group_id);
|
|
|
|
if (!$group_os) {
|
|
return response()->json(['error' => true, 'message' => 'Can\'t find Group Os']);
|
|
}
|
|
|
|
$os = Os::where('os_group_id', $group_id)->select('id', 'version')->get();
|
|
if ($os->count()) {
|
|
$os = array_map(function ($array) {
|
|
$array['name'] = $array['version'];
|
|
unset($array['version']);
|
|
return $array;
|
|
}, $os->all());
|
|
return response()->json(['error' => false, 'data' => $os]);
|
|
}
|
|
return response()->json(['error' => true, 'message' => 'Can\'t find Os by Os Group ID #' . $group_id]);
|
|
})->name('api.GetVersionOs');
|
|
Route::post('get-all-image', function (Media $media) {
|
|
$files = $media->getAllMedia();
|
|
$data = view('administrator.pages.component.media')->with('media', $files)->render();
|
|
return response()->json(['data' => $data]);
|
|
})->name('api.GetAllImage');
|
|
Route::get('get-list-addon', function () {
|
|
$product = request()->input('product');
|
|
if (!$product) {
|
|
return response()->json(['error' => true, 'data' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
|
|
$allAddon = Addon::get();
|
|
$formAddon = view('administrator.pages.component.addon')->with([
|
|
'addon' => $allAddon
|
|
])->render();
|
|
|
|
return response()->json(['error' => false, 'data' => $formAddon]);
|
|
})->name('api.GetAddonProduct');
|
|
Route::post('add-addon-to-product', function (Request $request) {
|
|
$order = $request->order;
|
|
$product = $request->product;
|
|
$cpu = $request->cpu;
|
|
$ram = $request->ram;
|
|
$ssd = $request->ssd;
|
|
if (!$cpu && !$ram && !$ssd) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid Request']);
|
|
}
|
|
if (!$product) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid Request']);
|
|
}
|
|
$product = ModuleVmware::find($request->product);
|
|
|
|
if (!$product) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid Request']);
|
|
}
|
|
|
|
if ($order && $order != $product->order_id) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid Request']);
|
|
}
|
|
$invoice_id = 0;
|
|
$billing_sw = 0;
|
|
$order = \App\Models\Order::with('OrderItem')->find($product->order_id);
|
|
if ($order && $order->OrderItem) {
|
|
$order_item = $order->OrderItem->first();
|
|
$invoice_id = $order_item->invoice_id;
|
|
$billing_sw = $order_item->billing;
|
|
}
|
|
$invoice = Invoice::find($invoice_id);
|
|
|
|
if (!$invoice) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid Request']);
|
|
}
|
|
|
|
$addon = [];
|
|
$item = [];
|
|
$total = 0;
|
|
if ($cpu) {
|
|
$item['cpu'] = $cpu;
|
|
}
|
|
if ($ram) {
|
|
$item['ram'] = $ram;
|
|
}
|
|
if ($ssd) {
|
|
$item['ssd'] = $ssd;
|
|
}
|
|
foreach ($item as $key => $value) {
|
|
$addonItem = Addon::where('name', 'like', "%$key%")->first();
|
|
|
|
$message = "Addon " . strtoupper($key);
|
|
switch ($billing_sw) {
|
|
case 2:
|
|
$billing = 1;
|
|
$message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::now()->addMonths(1)->format('d/m/Y') . " )";
|
|
break;
|
|
case 3:
|
|
$billing = 3;
|
|
$message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::now()->addMonths(3)->format('d/m/Y') . " )";
|
|
break;
|
|
case 4:
|
|
$billing = 6;
|
|
$message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::now()->addMonths(6)->format('d/m/Y') . " )";
|
|
break;
|
|
case 5:
|
|
$billing = 12;
|
|
$message .= " ( " . Carbon::today()->format('d/m/Y') . " - " . Carbon::now()->addMonths(12)->format('d/m/Y') . " )";
|
|
break;
|
|
}
|
|
$addon[] = [
|
|
'customer_id' => $product->customer_id,
|
|
'type_id' => 1,
|
|
'due_date' => Carbon::now()->hour(23)->minute(59)->second(59)->timestamp,
|
|
'product_id' => $addonItem->id,
|
|
'parent_id' => $product->id,
|
|
'relid' => 0,
|
|
'description' => $message,
|
|
'invoice_type' => "1",
|
|
'billing' => $billing_sw,
|
|
'amount' => $addonItem->price * $value * $billing,
|
|
'tax' => 1,
|
|
];
|
|
$total += $addonItem->price * $value * $billing;
|
|
}
|
|
try {
|
|
DB::beginTransaction();
|
|
if ($order !== 0) {
|
|
$order->increment('amount', ($total + (0.1 * $total)));
|
|
$invoice->increment('total', ($total + (0.1 * $total)));
|
|
$invoice->increment('tax', 0.1 * $total);
|
|
$invoice->increment('sub_total', $total);
|
|
$product->increment('first_payment', $total);
|
|
$product->increment('next_payment', $total);
|
|
$allAddon = array_map(function ($item) use ($invoice) {
|
|
$item['invoice_id'] = $invoice->id;
|
|
return $item;
|
|
}, $addon);
|
|
InvoiceItem::insert($allAddon);
|
|
|
|
$addonInsert = InvoiceItem::select('id')->latest('id')->take(count($allAddon))->get();
|
|
|
|
foreach ($addonInsert as $item) {
|
|
DB::table('order__order_item')->insert([
|
|
'order_id' => $order->id,
|
|
'InvoiceItem_id' => $item->id
|
|
]);
|
|
}
|
|
} else {
|
|
$invoice_added = Invoice::insertGetId([
|
|
'date' => Carbon::now()->timestamp,
|
|
'due_date' => $product->next_due_date,
|
|
'sub_total' => $total,
|
|
'tax' => $total * 0.1,
|
|
'total' => $total + ($total * 0.1),
|
|
'payment_id' => 1,
|
|
'customer_id' => $product->customer_id,
|
|
'invoice_type' => 1,
|
|
'status' => 0
|
|
]);
|
|
$order_id = \App\Models\Order::insertGetId([
|
|
'order_num' => App\Http\Helpers\Helper::generateUniqueCode(),
|
|
'customer_id' => $product->customer_id,
|
|
'user_id' => $request->user()->id,
|
|
'date' => Carbon::now()->timestamp,
|
|
'payment_id' => 1,
|
|
'invoice_id' => $invoice_added,
|
|
'amount' => $total + ($total * 0.1),
|
|
'client_ip' => $request->getClientIp(),
|
|
'status' => 0
|
|
]);
|
|
|
|
$allAddon = array_map(function ($item) use ($invoice_added) {
|
|
$item['invoice_id'] = $invoice_added;
|
|
return $item;
|
|
}, $addon);
|
|
|
|
InvoiceItem::insert($allAddon);
|
|
|
|
$addonInsert = InvoiceItem::select('id')->latest('id')->take(count($allAddon))->get();
|
|
|
|
foreach ($addonInsert as $item) {
|
|
DB::table('order__order_item')->insert([
|
|
'order_id' => $order_id,
|
|
'InvoiceItem_id' => $item->id
|
|
]);
|
|
}
|
|
}
|
|
DB::commit();
|
|
} catch (Exception $exception) {
|
|
DB::rollBack();
|
|
return response()->json(['error' => true, 'message' => $exception->getMessage()]);
|
|
}
|
|
return response()->json(['error' => false, 'message' => 'Added Addon to Product Successfully']);
|
|
})->name('api.AcceptAddon');
|
|
Route::post('create-slug', function (Request $request) {
|
|
return Str::slug($request->get('name'));
|
|
})->name('api.CreateSlug');
|
|
Route::post('get-service-product', function (Request $request) {
|
|
$validate = Validator::make(
|
|
$request->all(),
|
|
[
|
|
'host' => 'required|numeric'
|
|
]
|
|
);
|
|
if ($validate->failed()) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid request']);
|
|
}
|
|
|
|
$host = ModuleHost::with('Datacenter.vCenter')->find($request->host);
|
|
|
|
if (!$host) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid request']);
|
|
}
|
|
|
|
|
|
$datacenter = ModuleDatacenter::where('vcenter_id', $host->Datacenter->vcenter_id)->select(
|
|
'id',
|
|
'name'
|
|
)->get();
|
|
$allHost = ModuleHost::where('module_datacenter_id', $host->module_datacenter_id)->select(
|
|
'id',
|
|
'name'
|
|
)->get();
|
|
$vcenter = vCenter::select('id', 'host')->get();
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => [
|
|
'host' => $allHost,
|
|
'datacenter' => $datacenter,
|
|
'vcenter' => $vcenter,
|
|
'choose' => [
|
|
'datacenter' => $host->module_datacenter_id,
|
|
'vcenter' => $host->Datacenter->vcenter_id,
|
|
'host' => $request->host
|
|
]
|
|
]
|
|
]);
|
|
})->name('api.GetServiceProduct');
|
|
Route::post('update-file-customer', function (Request $request) {
|
|
$validate = Validator::make(
|
|
$request->all(),
|
|
[
|
|
'user_id' => 'required|numeric',
|
|
'file' => 'required|string'
|
|
]
|
|
);
|
|
if ($validate->failed()) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid request']);
|
|
}
|
|
|
|
$user = Customer::find($request->user_id);
|
|
|
|
if (!$user) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid request']);
|
|
}
|
|
|
|
$fileName = str_replace(env('APP_URL') . '/uploads/files/', '', $request->file);
|
|
|
|
$file = File::insertGetId([
|
|
'filename' => $fileName,
|
|
'file_url' => $request->file,
|
|
'customer_id' => $request->user_id
|
|
]);
|
|
|
|
if ($file) {
|
|
return response()->json(['error' => false, 'message' => 'New file updated successfully']);
|
|
}
|
|
return response()->json(['error' => true, 'message' => 'Invalid request']);
|
|
})->name('api.CustomerUpdateFile');
|
|
Route::post('remove-file-customer', function (Request $request) {
|
|
$validate = Validator::make(
|
|
$request->all(),
|
|
[
|
|
'file' => 'required|numeric'
|
|
]
|
|
);
|
|
if ($validate->failed()) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid request']);
|
|
}
|
|
|
|
$file = File::find($request->file);
|
|
|
|
if (!$file) {
|
|
return response()->json(['error' => true, 'message' => 'Invalid request']);
|
|
}
|
|
|
|
$file->delete();
|
|
|
|
return response()->json(['error' => false, 'message' => 'The request was processed successfully']);
|
|
})->name('api.CustomerRemoveFile');
|
|
});
|
|
})
|
|
/* Api for customer */
|
|
->group(function () {
|
|
Route::middleware(['api.auth'])
|
|
->group(function () {
|
|
Route::post('get-status-virtual-machine', function (Request $request, ServiceVCenter $serviceVCenter) {
|
|
$vmware_id = $request->vmware_id;
|
|
$product_id = $request->product_id;
|
|
if (!$vmware_id || !$product_id) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
$product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')->find($product_id);
|
|
|
|
if (!$product) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
|
|
if ($vmware_id != $product->vmware_id) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
if ($product->status == 4) {
|
|
return response()->json(['error' => false, 'message' => 'Dịch vụ hết hạn', 'expiry' => true]);
|
|
}
|
|
if ($product->status == 3) {
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => 'Đang khởi tạo',
|
|
'expiry' => false,
|
|
'pending' => true
|
|
]);
|
|
}
|
|
|
|
$serviceVCenter->token = $product->ipAddress->host->datacenter->vCenter->token;
|
|
$serviceVCenter->apiUri = $product->ipAddress->host->datacenter->vCenter->host;
|
|
|
|
$VirtualMachine = $serviceVCenter->CheckVirtualMachine($vmware_id);
|
|
|
|
if ($VirtualMachine === 'Login_Again') {
|
|
$token = $serviceVCenter->loginServer($product->ipAddress->host->datacenter->vCenter);
|
|
if ($token) {
|
|
vCenter::where(
|
|
'id',
|
|
$product->ipAddress->host->datacenter->vCenter->id
|
|
)->update(['token' => $token]);
|
|
$serviceVCenter->token = $token;
|
|
}
|
|
$VirtualMachine = $serviceVCenter->CheckVirtualMachine($vmware_id);
|
|
}
|
|
|
|
// Check if VirtualMachine is still a string (Login_Again or other error)
|
|
if (is_string($VirtualMachine)) {
|
|
return response()->json(['error' => true, 'message' => "Failed to check virtual machine: $VirtualMachine"]);
|
|
}
|
|
|
|
if ($VirtualMachine['error']) {
|
|
return response()->json(['error' => true, 'message' => $VirtualMachine['message']]);
|
|
}
|
|
$status = 3;
|
|
if ($VirtualMachine['data']['state'] === 'RUNNING') {
|
|
$product->update([
|
|
'status' => 1
|
|
]);
|
|
}
|
|
if ($VirtualMachine['data']['state'] === 'NOT_RUNNING') {
|
|
$product->update([
|
|
'status' => 0
|
|
]);
|
|
}
|
|
|
|
$product = ModuleVmware::find($product_id);
|
|
|
|
$data = view('form.action')->with([
|
|
'user' => $request->user('')->id,
|
|
'item' => $product
|
|
])->render();
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => $VirtualMachine['data'],
|
|
'expiry' => false,
|
|
'data' => $data
|
|
]);
|
|
})->name('api.GetVirtualMachineStatus');
|
|
Route::get('get-list-group-os', function () {
|
|
$host_id = \request()->get('host');
|
|
if (!$host_id) {
|
|
return response()->json(['error' => true, 'message' => 'Please choose Host']);
|
|
}
|
|
$host = ModuleHost::find($host_id);
|
|
|
|
if (!$host) {
|
|
return response()->json(['error' => true, 'message' => 'Can\'t find Host']);
|
|
}
|
|
|
|
$osGroup = OsGroup::where('ModuleHost_id', $host_id)->select('id', 'name')->get();
|
|
if ($osGroup->count()) {
|
|
return response()->json(['error' => false, 'data' => $osGroup->all()]);
|
|
}
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Can\'t find OsGroup by Host ID #' . $host_id
|
|
]);
|
|
})->name('api.user.getOsGroup');
|
|
Route::get('get-list-version-os', function () {
|
|
$group_id = \request()->get('group');
|
|
if (!$group_id) {
|
|
return response()->json(['error' => true, 'message' => 'Please choose Host']);
|
|
}
|
|
$group_os = OsGroup::find($group_id);
|
|
|
|
if (!$group_os) {
|
|
return response()->json(['error' => true, 'message' => 'Can\'t find Group Os']);
|
|
}
|
|
|
|
$os = Os::where('os_group_id', $group_id)->select('id', 'version')->get();
|
|
if ($os->count()) {
|
|
$os = array_map(function ($array) {
|
|
$array['name'] = $array['version'];
|
|
unset($array['version']);
|
|
return $array;
|
|
}, $os->all());
|
|
return response()->json(['error' => false, 'data' => $os]);
|
|
}
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Can\'t find Os by Os Group ID #' . $group_id
|
|
]);
|
|
})->name('api.user.GetVersionOs');
|
|
Route::get('list-snapshot', function () {
|
|
$product_id = request()->input('product');
|
|
$user_id = request()->input('user');
|
|
if (!$product_id || !$user_id) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
|
|
$snapshot = ModuleSnapshot::where(function ($query) use ($product_id, $user_id) {
|
|
$query->where('customer_id', $user_id);
|
|
$query->where('ModuleVmware_id', $product_id);
|
|
})->get();
|
|
$data = view('form.snapshot')->with([
|
|
'snapshot' => $snapshot,
|
|
'user' => $user_id,
|
|
'product' => $product_id
|
|
])->render();
|
|
return response()->json(['error' => false, 'data' => $data]);
|
|
})->name('api.user.GetSnapshot');
|
|
Route::get('get-list-addon', function () {
|
|
$product = request()->input('product');
|
|
if (!$product) {
|
|
return response()->json(['error' => true, 'data' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
$billing = InvoiceItem::select('billing')
|
|
->where('type_id', 4)
|
|
->where('relid', $product)->first();
|
|
if (!$billing) {
|
|
return response()->json(['error' => true, 'data' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
$allAddon = Addon::get();
|
|
$formAddon = view('form.upgrade')->with([
|
|
'addon' => $allAddon,
|
|
'billing' => $billing->billing,
|
|
'product' => $product
|
|
])->render();
|
|
|
|
return response()->json(['error' => false, 'data' => $formAddon]);
|
|
})->name('api.user.GetAddonProduct');
|
|
Route::post('payment-invoice', function () {
|
|
$invoice_id = \request()->input('invoice');
|
|
if (!$invoice_id) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
$invoice = Invoice::with('Order', 'InvoiceItem')->find($invoice_id);
|
|
|
|
if (!$invoice) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
if ($invoice->status == 1) {
|
|
return response()->json(['error' => true, 'message' => 'Hoá đơn đã được thanh toán!']);
|
|
}
|
|
$customer = Customer::find(auth()->id());
|
|
|
|
if (!$customer) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
|
|
if ($customer->credit < $invoice->total) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Tài khoản của quý khách không đủ để thực hiện thanh toán'
|
|
]);
|
|
}
|
|
$products = [];
|
|
$next_due_date = 0;
|
|
$next_invoice = 0;
|
|
if ($invoice->InvoiceItem->count()) {
|
|
foreach ($invoice->InvoiceItem->where('relid', '<>', 0) as $item) {
|
|
$product = $item->GetRelidProduct();
|
|
$products[] = $product;
|
|
$time = $product->next_due_date;
|
|
switch ($item->billing) {
|
|
case 2:
|
|
$next_due_date = Carbon::parse($time)->addMonths(1)->timestamp;
|
|
$next_invoice = Carbon::parse($time)->addMonths(1)->timestamp;
|
|
break;
|
|
case 3:
|
|
$next_due_date = Carbon::parse($time)->addMonths(3)->timestamp;
|
|
$next_invoice = Carbon::parse($time)->addMonths(3)->timestamp;
|
|
break;
|
|
case 4:
|
|
$next_due_date = Carbon::parse($time)->addMonths(6)->timestamp;
|
|
$next_invoice = Carbon::parse($time)->addMonths(6)->timestamp;
|
|
break;
|
|
case 5:
|
|
$next_due_date = Carbon::parse($time)->addMonths(12)->timestamp;
|
|
$next_invoice = Carbon::parse($time)->addMonths(12)->timestamp;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
try {
|
|
DB::beginTransaction();
|
|
$customer->update([
|
|
'credit' => ($customer->credit - $invoice->total)
|
|
]);
|
|
|
|
$invoice->update([
|
|
'status' => 1,
|
|
'date_paid' => time()
|
|
]);
|
|
|
|
$order = $invoice->Order;
|
|
$jobs = [];
|
|
if ($order && $order->status !== 1 && $invoice->invoice_type == 1) {
|
|
$order->update([
|
|
'status' => 1
|
|
]);
|
|
$addon = [];
|
|
$product = 0;
|
|
foreach (
|
|
$order->OrderItem->where('parent_id', 0)->whereIn(
|
|
'type_id',
|
|
[3, 4]
|
|
) as $key => $item
|
|
) {
|
|
if ($item->type_id == 3) {
|
|
$Server = ModuleHostingServer::where('status', 1)->first();
|
|
ModuleHosting::find($item->relid)->update(['module_server_id' => $Server->id]);
|
|
$jobs[] = new CreateHostingJobs($item->relid);
|
|
} else {
|
|
$product = $item->GetRelidProduct();
|
|
$os = Os::with('OsGroup')->find($product->os_id);
|
|
if ($os && $os->OsGroup) {
|
|
$ipaddress = ModuleIpAddress::where(
|
|
'ModuleHost_id',
|
|
$os->OsGroup->ModuleHost_id
|
|
)->where('status', 0)->first();
|
|
if ($ipaddress) {
|
|
$product->update([
|
|
'ModuleIpAddress_id' => $ipaddress->id
|
|
]);
|
|
$ipaddress->update([
|
|
'status' => 1
|
|
]);
|
|
$jobs[] = new CreateVMJobs($product->id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach ($order->OrderItem as $item) {
|
|
if ($item->type_id == 1) {
|
|
$itemData = $item->GetItemProduct();
|
|
|
|
$price = 0;
|
|
|
|
switch ($item->billing) {
|
|
case 2:
|
|
$price = $item->amount / 1;
|
|
break;
|
|
case 3:
|
|
$price = $item->amount / 3;
|
|
break;
|
|
case 4:
|
|
$price = $item->amount / 6;
|
|
break;
|
|
case 5:
|
|
$price = $item->amount / 12;
|
|
break;
|
|
}
|
|
$addon[strtolower($itemData->name)] = (int) $price / $itemData->price;
|
|
$product = $item->parent_id;
|
|
}
|
|
}
|
|
|
|
if ($order->OrderItem->count() === count($addon)) {
|
|
dispatch(new UpgradeVirtualMachine(
|
|
$product,
|
|
$addon,
|
|
$order->id
|
|
))->delay(now()->addSeconds(10));
|
|
}
|
|
} else {
|
|
foreach ($products as $item) {
|
|
if (isset($item->vmware_id)) {
|
|
$jobs[] = new \App\Jobs\VirtualMachine\Action\VMJobs($item->id, 'Start', true);
|
|
}
|
|
if (isset($item->server_domain_id)) {
|
|
$jobs[] = new \App\Jobs\Hosting\HostingJobs($item->id, 'Activate');
|
|
}
|
|
$item->update([
|
|
'next_due_date' => $next_due_date,
|
|
'next_invoice' => $next_invoice
|
|
]);
|
|
}
|
|
}
|
|
if (count($jobs)) {
|
|
foreach ($jobs as $item) {
|
|
dispatch($item)->delay(now()->addSeconds(10));
|
|
}
|
|
}
|
|
DB::commit();
|
|
} catch (Exception $exception) {
|
|
DB::rollBack();
|
|
return response()->json(['error' => true, 'message' => $exception->getMessage()]);
|
|
}
|
|
return response()->json(['error' => false, 'message' => "Thanh toán hoá đơn thành công"]);
|
|
})->name('api.user.PaymentInvoice');
|
|
Route::post('renew-services', function () {
|
|
$product_id = \request()->input('product');
|
|
$type_id = \request()->input('type');
|
|
$billing = \request()->input('billing');
|
|
if (!$product_id || !$type_id || !$billing) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
$product = null;
|
|
|
|
switch ($type_id) {
|
|
case 3:
|
|
$product = ModuleHosting::find($product_id);
|
|
break;
|
|
case 4:
|
|
$product = ModuleVmware::find($product_id);
|
|
break;
|
|
}
|
|
if (!$product) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
|
|
$customer = Customer::find(auth()->id());
|
|
if (!$customer) {
|
|
return response()->json(['error' => true, 'message' => 'Yêu cầu không hợp lệ']);
|
|
}
|
|
|
|
$item = InvoiceItem::where(function ($query) use ($product_id, $type_id) {
|
|
$query->where('invoice_type', 1);
|
|
|
|
$query->where(function ($_query) use ($product_id) {
|
|
$_query->where('relid', $product_id);
|
|
$_query->Orwhere('parent_id', $product_id);
|
|
});
|
|
if ($type_id == 4) {
|
|
$query->whereIn('type_id', [1, 4]);
|
|
} else {
|
|
$query->where('type_id', $type_id);
|
|
}
|
|
})->get();
|
|
$nextPay = (int) $product->next_payment;
|
|
|
|
$renew_item = [];
|
|
|
|
if ($item->count()) {
|
|
foreach ($item as $key => $_item) {
|
|
$renew_item[$key] = $_item->replicate();
|
|
$subMessage = '';
|
|
switch ((int) $billing) {
|
|
case 2:
|
|
$subMessage = " ( " . Carbon::parse($product->next_due_date)->format('d/m/Y') . " - " . Carbon::parse($product->next_due_date)->addMonths(1)->format('d/m/Y') . " )";
|
|
break;
|
|
case 3:
|
|
$subMessage = " ( " . Carbon::parse($product->next_due_date)->format('d/m/Y') . " - " . Carbon::parse($product->next_due_date)->addMonths(3)->format('d/m/Y') . " )";
|
|
break;
|
|
case 4:
|
|
$subMessage = " ( " . Carbon::parse($product->next_due_date)->format('d/m/Y') . " - " . Carbon::parse($product->next_due_date)->addMonths(6)->format('d/m/Y') . " )";
|
|
break;
|
|
case 5:
|
|
$subMessage = " ( " . Carbon::parse($product->next_due_date)->format('d/m/Y') . " - " . Carbon::parse($product->next_due_date)->addMonths(12)->format('d/m/Y') . " )";
|
|
break;
|
|
}
|
|
$renew_item[$key]->invoice_type = 0;
|
|
$renew_item[$key]->description = $_item->GetItemProduct()->name . $subMessage;
|
|
$renew_item[$key]->billing = $billing;
|
|
}
|
|
}
|
|
switch ((int) $billing) {
|
|
case 2:
|
|
$nextPay *= 1;
|
|
break;
|
|
case 3:
|
|
$nextPay *= 3;
|
|
break;
|
|
case 4:
|
|
$nextPay *= 6;
|
|
break;
|
|
case 5:
|
|
$nextPay *= 12;
|
|
break;
|
|
}
|
|
$date_exp = Carbon::now()->diffInDays(Carbon::parse($product->next_due_date), false);
|
|
$invoice_data = [
|
|
'date' => Carbon::now()->timestamp,
|
|
'due_date' => $date_exp > 0 ? $product->next_due_date : Carbon::now()->timestamp,
|
|
'payment_id' => 1,
|
|
'sub_total' => $nextPay,
|
|
'tax' => $nextPay * (10 / 100),
|
|
'total' => $nextPay + ($nextPay * (10 / 100)),
|
|
'invoice_type' => 0,
|
|
'customer_id' => $product->customer_id,
|
|
'status' => 0
|
|
];
|
|
try {
|
|
DB::beginTransaction();
|
|
$invoice_id = Invoice::insertGetId($invoice_data);
|
|
foreach ($renew_item as $item) {
|
|
$item->invoice_id = $invoice_id;
|
|
$item->save();
|
|
}
|
|
DB::commit();
|
|
} catch (Exception $exception) {
|
|
DB::rollBack();
|
|
return response()->json(['error' => true, 'message' => $exception->getMessage()]);
|
|
}
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => "Yêu cầu gia hạn được xử lý thành công. Vui lòng thanh toán hoá đơn để hoàn tất!"
|
|
]);
|
|
})->name('api.user.RenewService');
|
|
Route::get('get-ticket-console', function (Request $request, ServiceVCenter $serviceVCenter) {
|
|
$product_id = $request->get('product');
|
|
if (!$product_id) {
|
|
return response()->json(['error' => true, 'message' => "Please choose product"]);
|
|
}
|
|
$product = ModuleVmware::with('ipAddress.host.datacenter.vCenter')->find($product_id);
|
|
if (!$product) {
|
|
return response()->json(['error' => true, 'message' => "Can't find product"]);
|
|
}
|
|
|
|
// Validate that the product belongs to the authenticated user
|
|
if ($product->customer_id != user()->id) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không có quyền truy cập máy ảo này'
|
|
]);
|
|
}
|
|
|
|
// Check if service is expired
|
|
if ($product->status == 4) {
|
|
return response()->json(['error' => true, 'message' => 'Dịch vụ đã hết hạn']);
|
|
}
|
|
|
|
// Check if VM is still initializing
|
|
if ($product->status == 3) {
|
|
return response()->json(['error' => true, 'message' => 'Máy ảo đang khởi tạo']);
|
|
}
|
|
|
|
$vcenter = null;
|
|
if ($product->ipAddress && $product->ipAddress->host && $product->ipAddress->host->datacenter && $product->ipAddress->host->datacenter->vCenter) {
|
|
$vcenter = $product->ipAddress->host->datacenter->vCenter;
|
|
}
|
|
|
|
if (!$vcenter) {
|
|
return response()->json(['error' => true, 'message' => "Can't find vCenter information"]);
|
|
}
|
|
|
|
// Đăng nhập vCenter trước khi lấy ticket
|
|
if (!$serviceVCenter->loginServer($vcenter)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập vào vCenter'
|
|
]);
|
|
}
|
|
|
|
$ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id);
|
|
|
|
// Nếu login hết hạn, thử login lại 1 lần nữa
|
|
if ($ConsoleTicket === 'Login_Again') {
|
|
if ($serviceVCenter->loginServer($vcenter)) {
|
|
$ConsoleTicket = $serviceVCenter->GetConsoleTickets($product->vmware_id);
|
|
} else {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập lại vào vCenter'
|
|
]);
|
|
}
|
|
}
|
|
|
|
// Nếu vẫn lỗi, trả về lỗi rõ ràng
|
|
if (is_string($ConsoleTicket)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => "Failed to get console ticket: $ConsoleTicket"
|
|
]);
|
|
}
|
|
|
|
if ($ConsoleTicket['error']) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => $ConsoleTicket['data']
|
|
]);
|
|
}
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'data' => $ConsoleTicket['data'],
|
|
'host' => $vcenter->host,
|
|
'vmware-api-session-id' => $serviceVCenter->token
|
|
])->cookie('vmware-api-session-id', $serviceVCenter->token, 60, '/', null, false, false);
|
|
})->name('api.user.GetConsoleTicket');
|
|
|
|
|
|
Route::post('start-virtual-machine', function (Request $request, ServiceVCenter $serviceVCenter) {
|
|
$vm_id = $request->input('vm_id') ?: $request->json('vm_id');
|
|
if (!$vm_id) {
|
|
$jsonData = json_decode($request->getContent(), true);
|
|
$vm_id = $jsonData['vm_id'] ?? null;
|
|
}
|
|
|
|
if (!$vm_id) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Yêu cầu không hợp lệ - vm_id không được tìm thấy',
|
|
]);
|
|
}
|
|
|
|
$vm = ModuleVmware::where('vmware_id', $vm_id)->first();
|
|
|
|
if (!$vm) {
|
|
$vm = ModuleVmware::where('id', $vm_id)->first();
|
|
}
|
|
|
|
if (!$vm) {
|
|
$allVMs = ModuleVmware::where('vmware_id', 'like', '%' . $vm_id . '%')
|
|
->orWhere('id', 'like', '%' . $vm_id . '%')
|
|
->get();
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không tìm thấy thông tin máy ảo',
|
|
'debug' => [
|
|
'vm_id_received' => $vm_id,
|
|
'similar_vms_count' => $allVMs->count(),
|
|
'similar_vms' => $allVMs->toArray()
|
|
]
|
|
]);
|
|
}
|
|
|
|
if ($vm->customer_id != user()->id) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không có quyền truy cập máy ảo này'
|
|
]);
|
|
}
|
|
|
|
if ($vm->status == 4) {
|
|
return response()->json(['error' => true, 'message' => 'Dịch vụ đã hết hạn']);
|
|
}
|
|
|
|
if ($vm->status == 3) {
|
|
return response()->json(['error' => true, 'message' => 'Máy ảo đang khởi tạo']);
|
|
}
|
|
|
|
$vcenter = null;
|
|
if ($vm->ipAddress && $vm->ipAddress->host && $vm->ipAddress->host->datacenter && $vm->ipAddress->host->datacenter->vCenter) {
|
|
$vcenter = $vm->ipAddress->host->datacenter->vCenter;
|
|
}
|
|
|
|
if (!$vcenter) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không tìm thấy thông tin vCenter'
|
|
]);
|
|
}
|
|
|
|
if (!$serviceVCenter->loginServer($vcenter)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập vào vCenter'
|
|
]);
|
|
}
|
|
|
|
$result = $serviceVCenter->StartVirtualMachine($vm_id);
|
|
|
|
if ($result === "Login_Again") {
|
|
if ($serviceVCenter->loginServer($vcenter)) {
|
|
$result = $serviceVCenter->StartVirtualMachine($vm_id);
|
|
} else {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập lại vào vCenter'
|
|
]);
|
|
}
|
|
}
|
|
|
|
// Check if result is still a string (Login_Again or other error)
|
|
if (is_string($result)) {
|
|
return response()->json(['error' => true, 'message' => "Failed to start virtual machine: $result"]);
|
|
}
|
|
|
|
if ($result['error']) {
|
|
return response()->json(['error' => true, 'message' => $result['data']]);
|
|
}
|
|
|
|
$vm->update(['status' => 1]);
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => 'Khởi động máy ảo thành công'
|
|
]);
|
|
})->name('api.user.StartVirtualMachine');
|
|
|
|
Route::post('stop-virtual-machine', function (Request $request, ServiceVCenter $serviceVCenter) {
|
|
$vm_id = $request->input('vm_id') ?: $request->json('vm_id');
|
|
if (!$vm_id) {
|
|
$jsonData = json_decode($request->getContent(), true);
|
|
$vm_id = $jsonData['vm_id'] ?? null;
|
|
}
|
|
|
|
if (!$vm_id) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Yêu cầu không hợp lệ - vm_id không được tìm thấy'
|
|
]);
|
|
}
|
|
|
|
$vm = ModuleVmware::where('vmware_id', $vm_id)->first();
|
|
|
|
if (!$vm) {
|
|
$vm = ModuleVmware::where('id', $vm_id)->first();
|
|
}
|
|
|
|
if (!$vm) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không tìm thấy thông tin máy ảo'
|
|
]);
|
|
}
|
|
|
|
if ($vm->customer_id != user()->id) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không có quyền truy cập máy ảo này'
|
|
]);
|
|
}
|
|
|
|
if ($vm->status == 4) {
|
|
return response()->json(['error' => true, 'message' => 'Dịch vụ đã hết hạn']);
|
|
}
|
|
|
|
if ($vm->status == 3) {
|
|
return response()->json(['error' => true, 'message' => 'Máy ảo đang khởi tạo']);
|
|
}
|
|
|
|
$vcenter = null;
|
|
if ($vm->ipAddress && $vm->ipAddress->host && $vm->ipAddress->host->datacenter && $vm->ipAddress->host->datacenter->vCenter) {
|
|
$vcenter = $vm->ipAddress->host->datacenter->vCenter;
|
|
}
|
|
|
|
if (!$vcenter) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không tìm thấy thông tin vCenter'
|
|
]);
|
|
}
|
|
|
|
if (!$serviceVCenter->loginServer($vcenter)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập vào vCenter'
|
|
]);
|
|
}
|
|
|
|
$result = $serviceVCenter->ShutdownGuestVirtualMachine($vm_id);
|
|
|
|
if ($result === "Login_Again") {
|
|
if ($serviceVCenter->loginServer($vcenter)) {
|
|
$result = $serviceVCenter->ShutdownGuestVirtualMachine($vm_id);
|
|
} else {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập lại vào vCenter'
|
|
]);
|
|
}
|
|
}
|
|
|
|
// Check if result is still a string (Login_Again or other error)
|
|
if (is_string($result)) {
|
|
return response()->json(['error' => true, 'message' => "Failed to stop virtual machine: $result"]);
|
|
}
|
|
|
|
if ($result['error']) {
|
|
return response()->json(['error' => true, 'message' => $result['data']]);
|
|
}
|
|
|
|
$vm->update(['status' => 0]);
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => 'Tắt máy ảo thành công'
|
|
]);
|
|
})->name('api.user.StopVirtualMachine');
|
|
|
|
Route::get('get-ip-address', function (Request $request, ServiceVCenter $serviceVCenter) {
|
|
try {
|
|
$validator = Validator::make($request->all(), [
|
|
'vm_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);
|
|
}
|
|
|
|
$vmId = $request->input('vm_id');
|
|
$vm = ModuleVmware::where('vmware_id', $vmId)
|
|
->orWhere('id', $vmId)
|
|
->first();
|
|
|
|
if (!$vm) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không tìm thấy thông tin máy ảo'
|
|
], 404);
|
|
}
|
|
|
|
if ($vm->status == 4) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Dịch vụ đã hết hạn'
|
|
], 400);
|
|
}
|
|
|
|
if ($vm->status == 3) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Máy ảo đang khởi tạo'
|
|
], 400);
|
|
}
|
|
|
|
$vcenter = $vm->ipAddress->host->datacenter->vCenter ?? null;
|
|
|
|
if (!$vcenter) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không tìm thấy thông tin vCenter'
|
|
], 500);
|
|
}
|
|
|
|
if (!$serviceVCenter->loginServer($vcenter)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập vào vCenter'
|
|
], 500);
|
|
}
|
|
|
|
// Gọi 2 endpoint
|
|
$identity = Http::withoutVerifying()
|
|
->withHeaders(['vmware-api-session-id' => $serviceVCenter->token])
|
|
->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vm->vmware_id}/guest/identity")
|
|
->json();
|
|
|
|
$networking = Http::withoutVerifying()
|
|
->withHeaders(['vmware-api-session-id' => $serviceVCenter->token])
|
|
->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vm->vmware_id}/guest/networking")
|
|
->json();
|
|
|
|
// Parse IP
|
|
$ipAddresses = [];
|
|
|
|
// (1) Từ networking
|
|
if (isset($networking['value']['interfaces'])) {
|
|
foreach ($networking['value']['interfaces'] as $interface) {
|
|
foreach ($interface['ip_addresses'] ?? [] as $ip) {
|
|
if (isset($ip['ip_address']) && filter_var($ip['ip_address'], FILTER_VALIDATE_IP)) {
|
|
$ipAddresses[] = [
|
|
'ip' => $ip['ip_address'],
|
|
'type' => $ip['type'] ?? 'unknown',
|
|
'state' => $ip['state'] ?? 'unknown',
|
|
];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// (2) Nếu networking rỗng, fallback từ identity
|
|
if (empty($ipAddresses) && isset($identity['value']['ip_address'])) {
|
|
$ip = $identity['value']['ip_address'];
|
|
if (filter_var($ip, FILTER_VALIDATE_IP)) {
|
|
$ipAddresses[] = [
|
|
'ip' => $ip,
|
|
'type' => strpos($ip, ':') !== false ? 'IPV6' : 'IPV4',
|
|
'state' => 'unknown',
|
|
];
|
|
}
|
|
}
|
|
|
|
// Update trạng thái
|
|
if (!empty($ipAddresses)) {
|
|
$vm->update(['status' => 1]);
|
|
}
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => 'Lấy IP address thành công',
|
|
'data' => [
|
|
'vm_id' => $vm->vmware_id,
|
|
'hostname' => $vm->hostname,
|
|
'status' => $vm->status,
|
|
'ip_addresses' => $ipAddresses,
|
|
'guest_info' => [
|
|
'family' => $identity['value']['family'] ?? null,
|
|
'full_name' => $identity['value']['full_name']['default_message'] ?? null,
|
|
'host_name' => $identity['value']['host_name'] ?? null,
|
|
]
|
|
]
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('❌ Lỗi khi lấy IP address của VM', [
|
|
'vm_id' => $request->input('vm_id'),
|
|
'error' => $e->getMessage(),
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Lỗi hệ thống: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
})->name('api.user.GetIPAddress');
|
|
|
|
Route::get('get-vm-info', function (Request $request, ServiceVCenter $serviceVCenter) {
|
|
try {
|
|
$validator = Validator::make($request->all(), [
|
|
'vm_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);
|
|
}
|
|
|
|
$vmId = $request->input('vm_id');
|
|
|
|
$vcenter = vCenter::first();
|
|
|
|
if (!$vcenter) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không tìm thấy thông tin vCenter'
|
|
], 500);
|
|
}
|
|
|
|
// Sử dụng token có sẵn nếu có
|
|
$serviceVCenter->apiUri = $vcenter->host;
|
|
$serviceVCenter->token = $vcenter->token;
|
|
|
|
// Gọi API với timeout 5s
|
|
$vmInfo = Http::withoutVerifying()
|
|
->timeout(5)
|
|
->withHeaders(['vmware-api-session-id' => $serviceVCenter->token])
|
|
->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vmId}")
|
|
->json();
|
|
|
|
// Nếu token hết hạn, login lại 1 lần duy nhất
|
|
if (isset($vmInfo['type']) && str_contains($vmInfo['value']['messages'][0]['default_message'] ?? '', 'session')) {
|
|
if (!$serviceVCenter->loginServer($vcenter)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể đăng nhập vào vCenter'
|
|
], 500);
|
|
}
|
|
|
|
// Thử lại với token mới
|
|
$vmInfo = Http::withoutVerifying()
|
|
->timeout(5)
|
|
->withHeaders(['vmware-api-session-id' => $serviceVCenter->token])
|
|
->get("https://{$serviceVCenter->apiUri}/rest/vcenter/vm/{$vmId}")
|
|
->json();
|
|
}
|
|
|
|
if (isset($vmInfo['type'])) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Không thể lấy thông tin VM từ vCenter'
|
|
], 500);
|
|
}
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => 'Lấy thông tin VM thành công',
|
|
'data' => [
|
|
'vm_id' => $vmId,
|
|
'name' => $vmInfo['value']['name'] ?? 'Unknown',
|
|
'guest_os' => $vmInfo['value']['guest_OS'] ?? 'UNKNOWN',
|
|
'power_state' => $vmInfo['value']['power_state'] ?? 'UNKNOWN',
|
|
'cpu' => [
|
|
'count' => $vmInfo['value']['cpu']['count'] ?? 0,
|
|
'cores_per_socket' => $vmInfo['value']['cpu']['cores_per_socket'] ?? 0,
|
|
'hot_add_enabled' => $vmInfo['value']['cpu']['hot_add_enabled'] ?? false,
|
|
],
|
|
'memory' => [
|
|
'size_MiB' => $vmInfo['value']['memory']['size_MiB'] ?? 0,
|
|
'hot_add_enabled' => $vmInfo['value']['memory']['hot_add_enabled'] ?? false,
|
|
],
|
|
'disks' => array_map(function ($disk) {
|
|
return [
|
|
'key' => $disk['key'] ?? '',
|
|
'label' => $disk['value']['label'] ?? '',
|
|
'capacity' => $disk['value']['capacity'] ?? 0,
|
|
'type' => $disk['value']['type'] ?? '',
|
|
];
|
|
}, $vmInfo['value']['disks'] ?? []),
|
|
'nics' => array_map(function ($nic) {
|
|
return [
|
|
'key' => $nic['key'] ?? '',
|
|
'label' => $nic['value']['label'] ?? '',
|
|
'mac_address' => $nic['value']['mac_address'] ?? '',
|
|
'network_name' => $nic['value']['backing']['network_name'] ?? '',
|
|
'state' => $nic['value']['state'] ?? '',
|
|
];
|
|
}, $vmInfo['value']['nics'] ?? []),
|
|
'identity' => [
|
|
'instance_uuid' => $vmInfo['value']['identity']['instance_uuid'] ?? '',
|
|
'bios_uuid' => $vmInfo['value']['identity']['bios_uuid'] ?? '',
|
|
],
|
|
'hardware' => [
|
|
'version' => $vmInfo['value']['hardware']['version'] ?? '',
|
|
'upgrade_policy' => $vmInfo['value']['hardware']['upgrade_policy'] ?? '',
|
|
],
|
|
'boot' => [
|
|
'type' => $vmInfo['value']['boot']['type'] ?? '',
|
|
'efi_legacy_boot' => $vmInfo['value']['boot']['efi_legacy_boot'] ?? false,
|
|
]
|
|
],
|
|
'raw_data' => $vmInfo['value'] ?? null
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('❌ Lỗi khi lấy thông tin VM', [
|
|
'vm_id' => $request->input('vm_id'),
|
|
'error' => $e->getMessage(),
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'Lỗi hệ thống: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
})->name('api.user.GetVMInfo');
|
|
|
|
Route::get('get-vm-info/{vm_id}/{params?}', function (Request $request, ServiceVCenter $serviceVCenter, $vm_id, $params = null) {
|
|
try {
|
|
$vcenter = vCenter::first();
|
|
|
|
if (!$vcenter) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => __('vCenter configuration not found')
|
|
], 500);
|
|
}
|
|
|
|
// Login to vCenter first
|
|
if (!$serviceVCenter->loginServer($vcenter)) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => __('Cannot login to vCenter')
|
|
], 500);
|
|
}
|
|
|
|
$vmInfo = $serviceVCenter->GetDetailVirtualMachine($vm_id);
|
|
|
|
if ($vmInfo['error']) {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => __('Cannot get VM information from vCenter')
|
|
], 500);
|
|
}
|
|
|
|
$vmData = $vmInfo['data'];
|
|
|
|
// Parse các tham số được yêu cầu
|
|
$requestedParams = [];
|
|
if ($params) {
|
|
// Tách các param bằng dấu phẩy hoặc dấu +
|
|
$requestedParams = preg_split('/[,+]/', $params);
|
|
}
|
|
|
|
// Mapping dữ liệu đầy đủ
|
|
$allData = [
|
|
'vm_id' => $vm_id,
|
|
'name' => $vmData['name'] ?? 'Unknown',
|
|
'guest_os' => $vmData['guest_OS'] ?? 'UNKNOWN',
|
|
'power_state' => $vmData['power_state'] ?? 'UNKNOWN',
|
|
'cpu_count' => $vmData['cpu']['count'] ?? 0,
|
|
'cpu_cores_per_socket' => $vmData['cpu']['cores_per_socket'] ?? 0,
|
|
'cpu_hot_add' => $vmData['cpu']['hot_add_enabled'] ?? false,
|
|
'memory_size' => $vmData['memory']['size_MiB'] ?? 0,
|
|
'memory_hot_add' => $vmData['memory']['hot_add_enabled'] ?? false,
|
|
'instance_uuid' => $vmData['identity']['instance_uuid'] ?? '',
|
|
'bios_uuid' => $vmData['identity']['bios_uuid'] ?? '',
|
|
'hardware_version' => $vmData['hardware']['version'] ?? '',
|
|
'boot_type' => $vmData['boot']['type'] ?? '',
|
|
'efi_legacy_boot' => $vmData['boot']['efi_legacy_boot'] ?? false,
|
|
];
|
|
|
|
// Thêm thông tin disk
|
|
if (isset($vmData['disks']) && !empty($vmData['disks'])) {
|
|
$firstDisk = $vmData['disks'][0] ?? null;
|
|
if ($firstDisk) {
|
|
$allData['disk_capacity'] = $firstDisk['value']['capacity'] ?? 0;
|
|
$allData['disk_label'] = $firstDisk['value']['label'] ?? '';
|
|
$allData['disk_type'] = $firstDisk['value']['type'] ?? '';
|
|
}
|
|
}
|
|
|
|
// Thêm thông tin network
|
|
if (isset($vmData['nics']) && !empty($vmData['nics'])) {
|
|
$firstNic = $vmData['nics'][0] ?? null;
|
|
if ($firstNic) {
|
|
$allData['mac_address'] = $firstNic['value']['mac_address'] ?? '';
|
|
$allData['network_name'] = $firstNic['value']['backing']['network_name'] ?? '';
|
|
$allData['network_state'] = $firstNic['value']['state'] ?? '';
|
|
}
|
|
}
|
|
|
|
// Nếu không có params cụ thể, trả về tất cả
|
|
if (empty($requestedParams)) {
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => __('Successfully retrieved all VM information'),
|
|
'data' => $allData
|
|
]);
|
|
}
|
|
|
|
// Lọc chỉ những thông tin được yêu cầu
|
|
$filteredData = [];
|
|
foreach ($requestedParams as $param) {
|
|
$param = trim($param);
|
|
if (array_key_exists($param, $allData)) {
|
|
$filteredData[$param] = $allData[$param];
|
|
} else {
|
|
$filteredData[$param] = null; // Hoặc có thể bỏ qua
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'error' => false,
|
|
'message' => __('Successfully retrieved VM information'),
|
|
'data' => $filteredData
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('❌ Lỗi khi lấy thông tin VM với params', [
|
|
'vm_id' => $vm_id,
|
|
'params' => $params,
|
|
'error' => $e->getMessage(),
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => __('System error: :error', ['error' => $e->getMessage()])
|
|
], 500);
|
|
}
|
|
})->name('api.user.GetVMInfoWithParams');
|
|
});
|
|
|
|
});
|
|
|
|
Route::any('{any}', function () {
|
|
return response()->json([
|
|
'error' => true,
|
|
'message' => 'API Route not found'
|
|
], 404);
|
|
})->where('any', '.*');
|