prepare( 'INSERT INTO vm_requests (vm_name, domain_name, size, vcpus, ram_gb, disk_gb, requested_by, status, description, usernames, sudo_usernames) VALUES (:vm_name, :domain_name, :size, :vcpus, :ram_gb, :disk_gb, :requested_by, :status, :description, :usernames, :sudo_usernames)' ); $stmt->execute([ 'vm_name' => $vmName, 'domain_name' => $domain, 'size' => $size, 'vcpus' => $resources['vcpus'], 'ram_gb' => $resources['ram_gb'], 'disk_gb' => $resources['disk_gb'], 'requested_by' => $_SESSION['user'] ?? 'unknown', 'status' => 'queued', 'description' => $description, 'usernames' => $usernames, 'sudo_usernames' => $sudoUsernames, ]); // Get the inserted request ID $requestId = db()->lastInsertId(); // Create NetBox Virtual Machine for this request try { $netboxClient = getNetBoxClient(); // Find the first cluster (proxmox-cluster) $cluster = $netboxClient->findCluster('proxmox-cluster'); if (!$cluster) { throw new Exception('No NetBox cluster found.'); } $vm = $netboxClient->createVirtualMachine([ 'name' => $vmName, 'cluster_id' => $cluster['id'], 'vcpus' => $resources['vcpus'], 'ram_gb' => $resources['ram_gb'], 'disk_gb' => $resources['disk_gb'], 'domain' => $domain, 'description' => $description ?: ('Requested by ' . ($_SESSION['user'] ?? 'unknown')), 'usernames' => $usernames, 'sudo_usernames' => $sudoUsernames, ]); $netboxVmId = $vm['id'] ?? null; // Update the request with NetBox VM ID $stmt = db()->prepare( 'UPDATE vm_requests SET status = :status, netbox_device_id = :netbox_vm_id WHERE id = :id' ); $stmt->execute([ 'status' => 'deployed_to_netbox', 'netbox_vm_id' => $netboxVmId, 'id' => $requestId, ]); } catch (Exception $e) { error_log("NetBox integration failed: " . $e->getMessage()); // Request stays in 'queued' — admin can retry later } } catch (PDOException $exception) { if ($exception->getCode() !== '23000') { throw $exception; } header('Location: /create.php?size=' . urlencode($size) . '&error=' . urlencode('A VM request with that name already exists.')); exit; } header('Location: /requests.php?created=1'); exit;