From 0ad242a5576e5d3b9763283573b3bcee833540b6 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Wed, 24 May 2023 22:21:00 +0000 Subject: [PATCH] implement db as class, improve approveResources Signed-off-by: Arthur Lu --- db.js | 60 +++++++++++++++++++++++++++++--------------------------- main.js | 12 ++++++------ pve.js | 8 ++++++-- utils.js | 26 ++++++++++++------------ 4 files changed, 56 insertions(+), 50 deletions(-) diff --git a/db.js b/db.js index 9f45992..20369d3 100644 --- a/db.js +++ b/db.js @@ -1,33 +1,35 @@ import { readFileSync, writeFileSync } from "fs"; -let template = "localdb.json.template" -let filename = "localdb.json"; - -let db = JSON.parse(readFileSync(template)); -try { - load(); -} -catch { - save(); -} - -function load() { - db = JSON.parse(readFileSync(filename)); -} - -function save() { - writeFileSync(filename, JSON.stringify(db)); -} - -export function getResourceConfig() { - return db.resources; -} - -export function getUserConfig(username) { - if (db.users[username]) { - return db.users[username]; +class localdb { + #template = "localdb.json.template"; + #filename = "localdb.json"; + #data = null; + constructor () { + try { + this.load(this.#filename); + } + catch { + this.load(this.#template); + this.save(this.#filename); + } } - else { - return null; + load(path) { + this.#data = JSON.parse(readFileSync(path)); + } + save(path) { + writeFileSync(path, JSON.stringify(this.#data)); } -} \ No newline at end of file + getResourceConfig () { + return this.#data.resources; + } + getUserConfig (username) { + if (this.#data.users[username]) { + return this.#data.users[username]; + } + else { + return null; + } + } +} + +export const db = new localdb(); \ No newline at end of file diff --git a/main.js b/main.js index 787ab97..f20bb32 100644 --- a/main.js +++ b/main.js @@ -7,8 +7,8 @@ import api from "./package.json" assert {type: "json"}; import { pveAPIToken, listenPort, hostname, domain } from "./vars.js"; import { requestPVE, handleResponse, getDiskInfo } from "./pve.js"; -import { checkAuth, getAllocatedResources, approveResources } from "./utils.js"; -import { getUserConfig } from "./db.js"; +import { checkAuth, approveResources, getUserResources } from "./utils.js"; +import { db } from "./db.js"; const app = express(); app.use(bodyParser.urlencoded({ extended: true })); @@ -117,7 +117,7 @@ app.get("/api/user/resources", async (req, res) => { // check auth let auth = await checkAuth(req.cookies, res); if (!auth) { return; } - let resources = await getAllocatedResources(req, req.cookies.username); + let resources = await getUserResources(req, req.cookies.username); res.status(200).send(resources); }); @@ -131,7 +131,7 @@ app.get("/api/user/instances", async (req, res) => { // check auth let auth = await checkAuth(req.cookies, res); if (!auth) { return; } - let config = getUserConfig(req.cookies.username); + let config = db.getUserConfig(req.cookies.username); res.status(200).send(config.instances) }); @@ -145,7 +145,7 @@ app.get("/api/user/nodes", async (req, res) => { // check auth let auth = await checkAuth(req.cookies, res); if (!auth) { return; } - let config = getUserConfig(req.cookies.username); + let config = db.getUserConfig(req.cookies.username); res.status(200).send({ nodes: config.nodes }) }) @@ -514,7 +514,7 @@ app.post("/api/instance", async (req, res) => { let auth = await checkAuth(req.cookies, res); if (!auth) { return; } // get user db config - let user = await getUserConfig(req.cookies.username); + let user = await db.getUserConfig(req.cookies.username); let vmid = Number.parseInt(req.body.vmid); let vmid_min = user.instances.vmid.min; let vmid_max = user.instances.vmid.max; diff --git a/pve.js b/pve.js index d0e9aaa..39f72c6 100644 --- a/pve.js +++ b/pve.js @@ -88,10 +88,14 @@ export async function getUsedResources(req, resourceMeta) { } else if (diskprefixes.some(prefix => key.startsWith(prefix))) { let diskInfo = await getDiskInfo(instance.node, instance.type, instance.vmid, key); - used[diskInfo.storage] += Number(diskInfo.size); + if (diskInfo) { // only count if disk exists + used[diskInfo.storage] += Number(diskInfo.size); + } } else if (key.startsWith("net")) { - used.network += Number(config[key].split("rate=")[1].split(",")[0]); + if (config[key].includes("rate=")) { // only count instances with a rate limit + used.network += Number(config[key].split("rate=")[1].split(",")[0]); + } } } } diff --git a/utils.js b/utils.js index 7898fd3..ad1c34e 100644 --- a/utils.js +++ b/utils.js @@ -1,10 +1,10 @@ import { getUsedResources, requestPVE } from "./pve.js"; -import { getUserConfig, getResourceConfig } from "./db.js"; +import { db } from "./db.js"; export async function checkAuth(cookies, res, vmpath = null) { let auth = false; - if (getUserConfig(cookies.username) === null) { + if (db.getUserConfig(cookies.username) === null) { auth = false; res.status(401).send({ auth: auth, path: vmpath ? `${vmpath}/config` : "/version", error: `user ${cookies.username} not found in localdb` }); res.end(); @@ -27,10 +27,10 @@ export async function checkAuth(cookies, res, vmpath = null) { return auth; } -export async function getAllocatedResources(req, username) { - let dbResources = getResourceConfig(); +export async function getUserResources (req, username) { + let dbResources = db.getResourceConfig(); let used = await getUsedResources(req, dbResources); - let max = getUserConfig(username).resources.max; + let max = db.getUserConfig(username).resources.max; let avail = {}; Object.keys(max).forEach((k) => { avail[k] = max[k] - used[k]; @@ -39,20 +39,20 @@ export async function getAllocatedResources(req, username) { } export async function approveResources(req, username, request) { - - let avail = (await getAllocatedResources(req, username)).avail; - - let approved = true; + let avail = (await getUserResources(req, username)).avail; Object.keys(request).forEach((key) => { - if (!(key in avail)) { + if (!(key in avail)) { // if requested resource is not in avail, block approved = false; + return false; } - else if (isNaN(avail[key]) || isNaN(request[key])) { + else if (isNaN(avail[key]) || isNaN(request[key])) { // if either the requested or avail resource is NaN, block approved = false; + return false; } - else if (avail[key] - request[key] < 0) { + else if (avail[key] - request[key] < 0) { // if the avail resources is less than the requested resources, block approved = false; + return false; } }); - return approved; + return true; // if all requested resources pass, allow } \ No newline at end of file