minecluster/lib/database/queries/server-queries.js

253 lines
6.5 KiB
JavaScript
Raw Normal View History

import pg from "../postgres.js";
import {
deleteQuery,
insertQuery,
selectWhereAllQuery,
updateWhereAllQuery,
} from "../pg-query.js";
import ExpressClientError from "../../util/ExpressClientError.js";
const table = "servers";
const asExpressClientError = (e) => {
throw new ExpressClientError({ m: e.message, c: 409 });
};
const getMclName = (host, id) =>
`${host.toLowerCase().replaceAll(".", "-")}-${id}`;
export async function checkAuthorization(serverId, cairoId) {
2024-03-29 12:39:44 -06:00
console.log(
`Checking Authorization for user ${cairoId} for serverId ${serverId}`,
);
if (!cairoId) return false;
const q = selectWhereAllQuery(table, {
id: serverId,
owner_cairo_id: cairoId,
});
return (await pg.query(q)).length === 1;
}
export async function createServerEntry(cairoId, serverSpec) {
const {
name,
host,
version,
serverType: server_type,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
storage: storage_val,
extraPorts: extra_ports,
backupHost: backup_host,
backupBucket: backup_bucket_path,
backupId: backup_id,
backupKey: backup_key,
backupInterval: backup_interval,
} = serverSpec;
var q = insertQuery(table, {
name,
owner_cairo_id: cairoId,
host,
version,
server_type,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
storage: !storage_val || storage_val === "0" ? null : storage_val, // 0, undefined, null, or "0" becomes null
extra_ports,
backup_enabled: !!backup_interval ? true : null, // We already verified the payload, so any backup key will work
backup_host,
backup_bucket_path,
backup_id,
backup_key,
backup_interval,
});
q += "\n RETURNING *";
try {
const entries = await pg.query(q);
const {
id,
owner_cairo_id: ownerCairoId,
name,
host,
version,
server_type: serverType,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
storage,
extra_ports: extraPorts,
backup_enabled: backupEnabled,
backup_host: backupHost,
backup_bucket_path: backupPath,
backup_id: backupId,
backup_key: backupKey,
backup_interval: backupInterval,
} = entries[0];
const mclName = getMclName(host, id);
return {
name,
mclName,
id,
ownerCairoId,
host,
version,
serverType,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
storage,
extraPorts,
backupEnabled,
backupHost,
backupPath,
backupId,
backupKey,
backupInterval,
};
} catch (e) {
asExpressClientError(e);
}
}
export async function deleteServerEntry(serverId) {
if (!serverId) asExpressClientError({ message: "Server ID Required!" });
const q = deleteQuery(table, { id: serverId });
return pg.query(q).catch(asExpressClientError);
}
export async function getServerEntry(serverId) {
if (!serverId) asExpressClientError({ message: "Server ID Required!" });
const q = selectWhereAllQuery(table, { id: serverId });
try {
const serverSpecs = await pg.query(q);
if (serverSpecs.length === 0) return [];
if (!serverSpecs.length === 1)
throw Error("Multiple servers found with the same name!");
const {
id,
owner_cairo_id: ownerCairoId,
name,
host,
version,
server_type: serverType,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
storage,
extra_ports: extraPorts,
backup_enabled: backupEnabled,
backup_host: backupHost,
backup_bucket_path: backupPath,
backup_id: backupId,
backup_key: backupKey,
backup_interval: backupInterval,
} = serverSpecs[0];
const mclName = getMclName(host, id);
return {
name,
mclName,
id,
ownerCairoId,
host,
version,
serverType,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
storage,
extraPorts,
backupEnabled,
backupHost,
backupPath,
backupId,
backupKey,
backupInterval,
};
} catch (e) {
asExpressClientError(e);
}
}
export async function modifyServerEntry(serverSpec) {
const {
id,
// ownerCairoId: owner_cairo_id, // DIsabled! If these becomes a reqest, please create a new function!
name,
// host, // TODO: Can only be updated if service name is generic and non descriptive
version,
serverType: server_type,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
// storage, // DO NOT INCLUDE THIS KEY, Not all storage providers in kubernetes allow for dynamically resizable PVCs
extraPorts: extra_ports,
backupEnabled: backup_enabled,
backupHost: backup_host,
backupBucket: backup_bucket_path,
backupId: backup_id,
backupKey: backup_key,
backupInterval: backup_interval,
} = serverSpec;
const q =
updateWhereAllQuery(
table,
{
name,
// host, // TODO: Can only be updated if service name is generic and non descriptive
version,
server_type,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
// storage, // DO NOT INCLUDE THIS KEY, Not all storage providers in kubernetes allow for dynamically resizable PVCs
extra_ports,
backup_enabled,
backup_host,
backup_bucket_path,
backup_id,
backup_key,
backup_interval,
},
{ id },
) + ` RETURNING *;`;
try {
const entries = await pg.query(q);
const {
name,
host, // Should always read the database value
server_type: serverType,
storage,
extra_ports: extraPorts,
backup_enabled: backupEnabled,
backup_host: backupHost,
backup_bucket_path: backupPath,
backup_id: backupId,
backup_key: backupKey,
backup_interval: backupInterval,
} = entries[0];
const mclName = getMclName(host, id);
return {
name, // Could change
mclName, // Shouldn't change
id, // Won't change
2024-02-13 09:37:48 -07:00
host, // TODO: Can only be updated if service name is generic and non descriptive, this returns the host from the database
version,
serverType,
cpu, // TODO: Ignored for now by the K8S manifests
memory,
storage,
extraPorts,
backupEnabled,
backupHost,
backupPath,
backupId,
backupKey,
backupInterval,
};
} catch (e) {
asExpressClientError(e);
}
}
export async function getServerEntries() {
const q = `SELECT * FROM ${table}`;
return pg.query(q);
}