This commit is contained in:
baodev0
2026-07-23 08:48:09 +07:00
parent 5d3ed57b32
commit 9b65d58310
6 changed files with 67 additions and 24 deletions
@@ -18,7 +18,7 @@ class IpPoolController extends Controller
$filter = $request->get('filter');
$networkId = $request->get('network_id');
$query = IpPool::with('network:id,name,type,network');
$query = IpPool::with(['network:id,name,type,network', 'service:id,server_name,status,customer_id']);
if ($filter) {
$query->where('ip_address', 'like', "%{$filter}%");
@@ -99,7 +99,7 @@ class IpPoolController extends Controller
public function show(int $id): JsonResponse
{
$pool = IpPool::with('network:id,name,type,network')->find($id);
$pool = IpPool::with(['network:id,name,type,network', 'service:id,server_name,status,customer_id'])->find($id);
if (!$pool) {
return response()->json(['error' => true, 'message' => "Không tìm thấy IP Pool #{$id}"], 404);
@@ -119,6 +119,8 @@ class IpPoolController extends Controller
'gateway' => 'nullable|string|max:45',
'cidr' => 'nullable|integer|min:0|max:32',
'netmask' => 'nullable|string|max:45',
'status' => 'nullable|in:free,assigned,reserved',
'service_id' => 'nullable|integer|exists:services,id',
]);
$networkId = (int) $request->module_network_id;
@@ -170,6 +172,8 @@ class IpPoolController extends Controller
'gateway' => $request->gateway,
'cidr' => $request->cidr,
'netmask' => $netmask,
'status' => $request->status ?: 'free',
'service_id' => $request->service_id,
]);
// Mirror into module_ip_address so both tables stay in sync.
@@ -210,6 +214,8 @@ class IpPoolController extends Controller
'gateway' => 'nullable|string|max:45',
'cidr' => 'nullable|integer|min:0|max:32',
'netmask' => 'nullable|string|max:45',
'status' => 'nullable|in:free,assigned,reserved',
'service_id' => 'nullable|integer|exists:services,id',
]);
if (!filter_var($request->ip_address, FILTER_VALIDATE_IP)) {
@@ -236,8 +242,9 @@ class IpPoolController extends Controller
DB::beginTransaction();
try {
$pool->update([
...$request->only(['ip_address', 'module_network_id', 'gateway', 'cidr']),
...$request->only(['ip_address', 'module_network_id', 'gateway', 'cidr', 'service_id']),
'netmask' => $netmask,
'status' => $request->status ?: $pool->status,
]);
$hostId = ModuleNetwork::find($pool->module_network_id)?->module_host_id;
@@ -255,7 +262,7 @@ class IpPoolController extends Controller
DB::commit();
return response()->json(['error' => false, 'data' => $pool->fresh('network')]);
return response()->json(['error' => false, 'data' => $pool->fresh(['network', 'service:id,server_name,status,customer_id'])]);
} catch (\Exception $e) {
DB::rollBack();
return response()->json(['error' => true, 'message' => $e->getMessage()], 500);
@@ -384,6 +391,30 @@ class IpPoolController extends Controller
]);
}
/**
* Service IDs already tied to an IP — either directly via ip_pools.service_id,
* or indirectly via a VM (module_vmware) sitting on that IP. Used by the admin
* form to disable services that are already in use on another IP.
*/
public function usedServices(): JsonResponse
{
$direct = IpPool::whereNotNull('service_id')
->select(['id as ip_pool_id', 'service_id']);
$viaVm = DB::table('ip_pools as ip')
->join('module_ip_address as mia', function ($join) {
$join->on('mia.ip', '=', 'ip.ip_address')
->on('mia.module_network_id', '=', 'ip.module_network_id');
})
->join('module_vmware as mv', 'mv.module_ip_address', '=', 'mia.id')
->whereNotNull('mv.service_id')
->select(['ip.id as ip_pool_id', 'mv.service_id']);
$used = $direct->toBase()->union($viaVm)->get()->unique(fn ($row) => "{$row->service_id}-{$row->ip_pool_id}")->values();
return response()->json(['error' => false, 'data' => $used]);
}
public function networks(): JsonResponse
{
$networks = ModuleNetwork::select(['id', 'name', 'type', 'network', 'module_host_id'])
@@ -16,7 +16,7 @@ class OsGroupController extends Controller
public function index(Request $request): JsonResponse
{
$query = OsGroup::withCount('os')
->with(['os' => fn($q) => $q->with(['host.datacenter.vCenter', 'datastore', 'network'])->orderBy('version')])
->with(['os' => fn($q) => $q->with(['host.datacenter.vCenter', 'datastore', 'network', 'resourcePool', 'folder'])->orderBy('version')])
->when(
$request->get('filter'),
fn($q, $f) => $q->where('name', 'like', "%{$f}%")
@@ -50,7 +50,7 @@ class OsGroupController extends Controller
public function show(int $id): JsonResponse
{
$group = OsGroup::withCount('os')
->with(['os' => fn($q) => $q->with(['host.datacenter.vCenter', 'datastore', 'network'])->orderBy('version')])
->with(['os' => fn($q) => $q->with(['host.datacenter.vCenter', 'datastore', 'network', 'resourcePool', 'folder'])->orderBy('version')])
->find($id);
if (! $group) {
@@ -141,24 +141,30 @@ class OsGroupController extends Controller
private function formatOs(\App\Models\Os $os): array
{
$host = $os->relationLoaded('host') ? $os->host : null;
$datastore = $os->relationLoaded('datastore') ? $os->datastore : null;
$network = $os->relationLoaded('network') ? $os->network : null;
$host = $os->relationLoaded('host') ? $os->host : null;
$datastore = $os->relationLoaded('datastore') ? $os->datastore : null;
$network = $os->relationLoaded('network') ? $os->network : null;
$resourcePool = $os->relationLoaded('resourcePool') ? $os->resourcePool : null;
$folder = $os->relationLoaded('folder') ? $os->folder : null;
return [
'id' => $os->id,
'version' => $os->version,
'template_id' => $os->template_id,
'is_active' => (bool) $os->status,
'os_group_id' => $os->os_group_id,
'module_host_id' => $os->module_host_id,
'datastore_id' => $os->datastore_id,
'module_network_id' => $os->module_network_id,
'datastore_name' => $datastore?->name,
'network_name' => $network?->name,
'host_name' => $host?->name,
'datacenter_name' => $host?->datacenter?->name,
'vcenter_name' => $host?->datacenter?->vCenter?->host,
'id' => $os->id,
'version' => $os->version,
'template_id' => $os->template_id,
'is_active' => (bool) $os->status,
'os_group_id' => $os->os_group_id,
'module_host_id' => $os->module_host_id,
'datastore_id' => $os->datastore_id,
'module_network_id' => $os->module_network_id,
'resource_pool_id' => $os->resource_pool_id,
'folder_id' => $os->folder_id,
'datastore_name' => $datastore?->name,
'network_name' => $network?->name,
'host_name' => $host?->name,
'resource_pool_name' => $resourcePool?->name,
'folder_name' => $folder?->name,
'datacenter_name' => $host?->datacenter?->name,
'vcenter_name' => $host?->datacenter?->vCenter?->host,
];
}
}
@@ -262,7 +262,7 @@ class VCenterController extends Controller
'datastore' => $ds->datastore,
'store_type' => $ds->type,
'space' => $ds->space,
'space_gb' => $ds->space ? round($ds->space / 1024, 1) : null,
'space_gb' => $ds->space ? $ds->space / 1024 : null,
'status' => $ds->status,
'module_host_id' => $ds->module_host_id,
],
+1 -1
View File
@@ -16,7 +16,7 @@ class Client
public function loginServer(Vcenter $vcenterModel): bool|string
{
$this->apiUri = $vcenterModel->host;
$this->apiUri = 'console.tgs.com.vn';
$this->username = $vcenterModel->user;
$this->password = SignRSA::DecryptFunc($vcenterModel->password);
+5
View File
@@ -39,6 +39,11 @@ class IpPool extends Model
return $this->belongsTo(ModuleNetwork::class, 'module_network_id', 'id');
}
public function service()
{
return $this->belongsTo(Service::class, 'service_id');
}
public function virtualMachines()
{
return $this->hasMany(VirtualMachines::class, 'ip_pool_id');
+1
View File
@@ -579,6 +579,7 @@ Route::prefix('v1')
->controller(IpPoolController::class)
->group(function () {
Route::get('networks', 'networks')->middleware('perm:module-vcenter.view');
Route::get('used-services', 'usedServices')->middleware('perm:module-vcenter.view');
Route::get('/', 'index')->middleware('perm:module-vcenter.view');
Route::post('/', 'store')->middleware('perm:module-vcenter.manager');
Route::post('sync', 'sync')->middleware('perm:module-vcenter.manager');