$ids */ public function release(array $ids, ?string $note, User $admin): int { return DB::transaction(function () use ($ids, $note, $admin) { $pools = IpPool::whereIn('id', $ids)->lockForUpdate()->get(); $count = 0; foreach ($pools as $pool) { $mirrors = ModuleIpAddress::where('ip', $pool->ip_address)->get(); $vms = ModuleVmware::where('ip', $pool->ip_address) ->orWhereIn('module_ip_address', $mirrors->pluck('id')) ->get(); if ($pool->status === 'free' && $pool->service_id === null && $vms->isEmpty()) { continue; } $before = $pool->only(['status', 'customer_id', 'customer_name', 'service_name', 'service_id']); $this->detach($pool, $mirrors->pluck('id')->all(), $vms->pluck('id')->all()); IpPoolLog::record($pool, IpPoolLog::VM_RELEASED, $before['status'], [ 'customer_id' => $before['customer_id'], 'customer_name' => $before['customer_name'], 'service_name' => $before['service_name'], 'service_id' => $before['service_id'], 'vm_name' => $vms->pluck('name')->filter()->implode(', ') ?: null, 'user_id' => $admin->id, 'note' => $note ?: 'Giải phóng IP khỏi dịch vụ/VM', ]); $count++; } return $count; }); } /** * @param array $mirrorIds * @param array $vmIds */ private function detach(IpPool $pool, array $mirrorIds, array $vmIds): void { $pool->update([ 'status' => 'free', 'service_id' => null, 'customer_id' => null, 'customer_name' => null, 'service_name' => null, 'contact_email' => null, 'contact_cc' => null, 'revoked_at' => now()->toDateString(), ]); ModuleIpAddress::whereIn('id', $mirrorIds)->update(['status' => 0, 'vm_name' => null]); ModuleVmware::whereIn('id', $vmIds)->update(['ip' => null, 'module_ip_address' => null]); VirtualMachines::where('ip_pool_id', $pool->id) ->orWhere('ip', $pool->ip_address) ->update(['ip_pool_id' => null, 'ip' => null]); } }