implement db as class,

improve approveResources

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
This commit is contained in:
Arthur Lu 2023-05-24 22:21:00 +00:00
parent 7e7f9b2b55
commit 0ad242a557
4 changed files with 56 additions and 50 deletions

54
db.js
View File

@ -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);
}
}
load(path) {
this.#data = JSON.parse(readFileSync(path));
}
save(path) {
writeFileSync(path, JSON.stringify(this.#data));
}
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();

12
main.js
View File

@ -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;

4
pve.js
View File

@ -88,14 +88,18 @@ 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);
if (diskInfo) { // only count if disk exists
used[diskInfo.storage] += Number(diskInfo.size);
}
}
else if (key.startsWith("net")) {
if (config[key].includes("rate=")) { // only count instances with a rate limit
used.network += Number(config[key].split("rate=")[1].split(",")[0]);
}
}
}
}
}
return used;
}

View File

@ -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
}