Files
phpsite/send.php
alex 8c069ee82a Add usernames and sudo_usernames fields to VM request form
- DB: add usernames/sudo_usernames columns to vm_requests table
- create.php: add form inputs for usernames and sudo_usernames
- send.php: capture, validate, and store both fields in DB
- netbox_integration/netbox_api.php: pass custom_fields to NetBox VM API
- requests.php: show usernames/sudo_usernames in request list
2026-05-09 23:57:36 +02:00

121 lines
3.8 KiB
PHP
Executable File

<?php
declare(strict_types=1);
require __DIR__ . '/config.php';
require_login();
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo 'Method not allowed.';
exit;
}
if (!verify_csrf($_POST['csrf_token'] ?? null)) {
http_response_code(419);
echo 'Invalid CSRF token.';
exit;
}
$config = require __DIR__ . '/sizes.php';
$sizeMapping = $config['sizes'];
$allowedDomains = $config['domains'];
$vmName = trim((string) ($_POST['VM_Name'] ?? ''));
$size = trim((string) ($_POST['size'] ?? ''));
$domain = trim((string) ($_POST['domain'] ?? ''));
$description = trim((string) ($_POST['description'] ?? ''));
$usernames = trim((string) ($_POST['usernames'] ?? ''));
$sudoUsernames = trim((string) ($_POST['sudo_usernames'] ?? ''));
$errors = [];
if (!preg_match('/^[A-Za-z0-9][A-Za-z0-9._-]{1,63}$/', $vmName)) {
$errors[] = 'VM name must be 2-64 characters and use letters, numbers, dots, dashes, or underscores.';
}
if (!isset($sizeMapping[$size])) {
$errors[] = 'Invalid VM size.';
}
if (!in_array($domain, $allowedDomains, true)) {
$errors[] = 'Invalid domain.';
}
if ($errors) {
header('Location: /create.php?size=' . urlencode($size) . '&error=' . urlencode(implode(' ', $errors)));
exit;
}
$resources = $sizeMapping[$size];
try {
$stmt = db()->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;