import createServerResources from "../k8s/server-create.js"; import deleteServerResources from "../k8s/server-delete.js"; import { createServerEntry, deleteServerEntry, getServerEntry, modifyServerEntry, } from "../database/queries/server-queries.js"; import ExpressClientError, { sendError } from "../util/ExpressClientError.js"; import { toggleServer } from "../k8s/k8s-server-control.js"; const dnsRegex = new RegExp( `^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$`, ); function backupPayloadFilter(req, res) { const serverSpec = req.body; const { backupHost, backupBucket, backupId, backupKey, backupInterval } = serverSpec; // TODO: Impliment non creation time backups if ( !!backupHost || !!backupBucket || !!backupId || !!backupKey || !!backupInterval ) { // If any keys are required, all are required if ( !( !!backupHost && !!backupBucket && !!backupId && !!backupKey && !!backupInterval ) ) return res.status(400).send("All backup keys are required!"); if (!dnsRegex.test(backupHost)) return res.status(400).send("Backup Host invalid!"); } return "filtered"; } function payloadFilter(req, res) { const serverSpec = req.body; if (!serverSpec) return res.sendStatus(400); const { name, host, version, serverType, memory, extraPorts } = serverSpec; if (!name) return res.status(400).send("Server name is required!"); if (!host) return res.status(400).send("Server host is required!"); if (!dnsRegex.test(host)) return res.status(400).send("Hostname invalid!"); if (!version) return res.status(400).send("Server version is required!"); if (!serverType) return res.status(400).send("Server type is required!"); if (!memory) return res.status(400).send("Memory is required!"); if ( !!extraPorts && (!Array.isArray(extraPorts) || extraPorts.find((e) => typeof e !== "string" || e.length > 5)) ) return res .status(400) .send("Extra ports must be a list of strings with length of 5!"); return "filtered"; } function checkServerId(serverSpec) { if (!serverSpec) throw new ExpressClientError({ c: 400 }); if (!serverSpec.id) throw new ExpressClientError({ c: 400, m: "Server id missing!" }); } export async function createServer(req, res) { if (payloadFilter(req, res) !== "filtered") return; if (backupPayloadFilter(req, res) !== "filtered") return; const serverSpec = req.body; try { const serverEntry = await createServerEntry(serverSpec); await createServerResources(serverEntry); res.sendStatus(200); } catch (e) { sendError(res)(e); } } export async function deleteServer(req, res) { // Ensure spec is safe const serverSpec = req.body; try { checkServerId(serverSpec); } catch (e) { return sendError(res)(e); } const deleteEntry = deleteServerEntry(serverSpec.id); const deleteResources = deleteServerResources(serverSpec); Promise.all([deleteEntry, deleteResources]) .then(() => res.sendStatus(200)) .catch(sendError(res)); } export async function startServer(req, res) { // Ensure spec is safe const serverSpec = req.body; try { checkServerId(serverSpec); } catch (e) { return sendError(res)(e); } const { id } = serverSpec; toggleServer(id, true) .then(() => res.sendStatus(200)) .catch(sendError(res)); } export async function stopServer(req, res) { // Ensure spec is safe const serverSpec = req.body; try { checkServerId(serverSpec); } catch (e) { return sendError(res)(e); } const { id } = serverSpec; toggleServer(id, false) .then(() => res.sendStatus(200)) .catch(sendError(res)); } export async function getServer(req, res) { // Ensure spec is safe const serverSpec = req.body; try { checkServerId(serverSpec); } catch (e) { return sendError(res)(e); } const { id } = serverSpec; getServerEntry(id).then((s) => { delete s.backupKey; // Do not let this ever get to an API client s.backupBucket = s.backupPath; delete s.backupPath; delete s.backupId; // Do not let this ever get to an API client res.json(s); }); } export async function modifyServer(req, res) { if (payloadFilter(req, res) !== "filtered") return; const serverSpec = req.body; try { checkServerId(serverSpec); const serverEntry = await modifyServerEntry(serverSpec); // await createServerResources(serverEntry); res.sendStatus(200); } catch (e) { sendError(res)(e); } }