change localdb interface

This commit is contained in:
Arthur Lu 2023-10-23 22:09:31 +00:00
parent 2d7df40b04
commit bf8c8d1f00
10 changed files with 121 additions and 40 deletions

View File

@ -117,6 +117,58 @@
"useriso": {
"node": "examplenode1",
"storage": "cephfs"
},
"defaultuser": {
"resources": {
"cpu": [],
"cores": {
"max": 0
},
"memory": {
"max": 0
},
"swap": {
"max": 0
},
"local": {
"max": 0
},
"cephpl": {
"max": 0
},
"network": {
"max": 0
},
"pci": []
},
"nodes": [],
"cluster": {
"vmid": {
"min": -1,
"max": -1
},
"pool": ""
},
"templates": {
"instances": {
"lxc": {},
"qemu": {}
}
},
"network": {
"lxc": {
"type": "veth",
"bridge": "vmbr0",
"vlan": 10,
"ip": "dhcp",
"ip6": "dhcp"
},
"qemu": {
"type": "virtio",
"bridge": "vmbr0",
"vlan": 10
}
}
}
},
"users": {

View File

@ -7,12 +7,12 @@ class LocalDB {
constructor (path) {
try {
this.#path = path;
this.load();
this.pveAPI = this.getGlobalConfig().application.pveAPI;
this.pveAPIToken = this.getGlobalConfig().application.pveAPIToken;
this.listenPort = this.getGlobalConfig().application.listenPort;
this.hostname = this.getGlobalConfig().application.hostname;
this.domain = this.getGlobalConfig().application.domain;
this.#load();
this.pveAPI = this.getConfig().application.pveAPI;
this.pveAPIToken = this.getConfig().application.pveAPIToken;
this.listenPort = this.getConfig().application.listenPort;
this.hostname = this.getConfig().application.hostname;
this.domain = this.getConfig().application.domain;
}
catch {
console.log(`Error: ${path} was not found. Please follow the directions in the README to initialize localdb.json.`);
@ -21,34 +21,63 @@ class LocalDB {
}
/**
* Load db from local file system. Reads from file path store in filename.
* Load db from local file system. Reads from file path store in path.
*/
load () {
#load () {
this.#data = JSON.parse(readFileSync(this.#path));
}
/**
* Save db to local file system. Saves to file path stored in filename.
* Save db to local file system. Saves to file path stored in path.
*/
save () {
#save () {
writeFileSync(this.#path, JSON.stringify(this.#data));
}
/**
* Gets the global config object from db.
* @returns {Object} global config data.
*/
getGlobalConfig () {
getGlobal () {
return this.#data.global;
}
setGloal (config) {
this.#data.global = config;
this.#save();
}
/**
* Gets a specific user's config from db.
* @param {string} username of user to get config.
* @returns {Object} specific user config data.
*/
getUserConfig (username) {
return this.#data.users[username];
addUser (username, config = null) {
config = config ? config : this.#data.global.defaultuser;
this.#data.users[username] = config;
this.#save();
}
getUser (username) {
if (this.#data.users[username]) {
return this.#data.users[username];
}
else {
return null;
}
}
setUser (username, config) {
if (this.#data.users[username]) {
this.#data.users[username] = config;
this.#save();
return true;
}
else {
return false;
}
}
delUser (username) {
if (this.#data.users[username]) {
delete this.#data.users[username];
this.#save();
return true;
}
else {
return false;
}
}
}

View File

@ -37,7 +37,7 @@ router.get(`/:node(${nodeRegexP})/pci`, async (req, res) => {
if (!auth) {
return;
}
const userNodes = db.getUserConfig(req.cookies.username).nodes;
const userNodes = db.getUser(req.cookies.username).nodes;
if (!userNodes.includes(params.node)) {
res.status(401).send({ auth: false, path: params.node });
res.end();
@ -164,7 +164,7 @@ router.post(`${basePath}/create`, async (req, res) => {
return;
}
// get user db config
const user = await db.getUserConfig(req.cookies.username);
const user = await db.getUser(req.cookies.username);
const vmid = Number.parseInt(params.vmid);
const vmidMin = user.cluster.vmid.min;
const vmidMax = user.cluster.vmid.max;

View File

@ -95,7 +95,7 @@ router.post("/:disk/attach", async (req, res) => {
}
// target disk must be allowed according to source disk's storage options
const diskConfig = await getDiskInfo(params.node, config, `unused${params.source}`); // get target disk
const resourceConfig = db.getGlobalConfig().resources;
const resourceConfig = db.getGlobal().resources;
if (!resourceConfig[diskConfig.storage].disks.some(diskPrefix => params.disk.startsWith(diskPrefix))) {
res.status(500).send({ error: `Requested target ${params.disk} is not in allowed list [${resourceConfig[diskConfig.storage].disks}].` });
res.end();
@ -337,7 +337,7 @@ router.post("/:disk/create", async (req, res) => {
return;
}
// target disk must be allowed according to storage options
const resourceConfig = db.getGlobalConfig().resources;
const resourceConfig = db.getGlobal().resources;
if (!resourceConfig[params.storage].disks.some(diskPrefix => params.disk.startsWith(diskPrefix))) {
res.status(500).send({ error: `Requested target ${params.disk} is not in allowed list [${resourceConfig[params.storage].disks}].` });
res.end();

View File

@ -63,7 +63,7 @@ router.post("/:netid/create", async (req, res) => {
return;
}
// setup action
const nc = db.getUserConfig(req.cookies.username).templates.network[params.type];
const nc = db.getUser(req.cookies.username).network[params.type];
let action = {};
if (params.type === "lxc") {
action[`net${params.netid}`] = `name=${params.name},bridge=${nc.bridge},ip=${nc.ip},ip6=${nc.ip6},tag=${nc.vlan},type=${nc.type},rate=${params.rate}`;

View File

@ -126,7 +126,7 @@ router.post("/:hostpci/modify", async (req, res) => {
action[`hostpci${params.hostpci}`] = `${params.device},pcie=${params.pcie}`;
action = JSON.stringify(action);
// commit action
const rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobalConfig().application.pveroot));
const rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobal().application.pveroot));
if (!(rootauth.status === 200)) {
res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." });
res.end();
@ -206,7 +206,7 @@ router.post("/create", async (req, res) => {
action[`hostpci${hostpci}`] = `${params.device},pcie=${params.pcie}`;
action = JSON.stringify(action);
// commit action
const rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobalConfig().application.pveroot));
const rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobal().application.pveroot));
if (!(rootauth.status === 200)) {
res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." });
res.end();
@ -263,7 +263,7 @@ router.delete("/:hostpci/delete", async (req, res) => {
// setup action
const action = JSON.stringify({ delete: `hostpci${params.hostpci}` });
// commit action, need to use root user here because proxmox api only allows root to modify hostpci for whatever reason
const rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobalConfig().application.pveroot));
const rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobal().application.pveroot));
if (!(rootauth.status === 200)) {
res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." });
res.end();

View File

@ -20,7 +20,7 @@ router.get("/config/:key", async (req, res) => {
}
const allowKeys = ["resources"];
if (allowKeys.includes(params.key)) {
const config = db.getGlobalConfig();
const config = db.getGlobal();
res.status(200).send(config[params.key]);
}
else {

View File

@ -24,8 +24,8 @@ let prevState = {};
// target ms value
let targetMSTime = null;
const schemes = db.getGlobalConfig().clientsync.schemes;
const resourceTypes = db.getGlobalConfig().clientsync.resourcetypes;
const schemes = db.getGlobal().clientsync.schemes;
const resourceTypes = db.getGlobal().clientsync.resourcetypes;
/**
* GET - get list of supported synchronization schemes
* responses:
@ -164,7 +164,7 @@ if (schemes.interrupt.enabled) {
}
else {
wsServer.handleUpgrade(req, socket, head, (socket) => {
const pool = db.getUserConfig(cookies.username).cluster.pool;
const pool = db.getUser(cookies.username).cluster.pool;
wsServer.emit("connection", socket, cookies.username, pool);
});
}

View File

@ -43,7 +43,7 @@ router.get("/config/:key", async (req, res) => {
}
const allowKeys = ["resources", "cluster", "nodes"];
if (allowKeys.includes(params.key)) {
const config = db.getUserConfig(req.cookies.username);
const config = db.getUser(req.cookies.username);
res.status(200).send(config[params.key]);
}
else {
@ -64,7 +64,7 @@ router.get("/iso", async (req, res) => {
return;
}
// get user iso config
const userIsoConfig = db.getGlobalConfig().useriso;
const userIsoConfig = db.getGlobal().useriso;
// get all isos
const isos = (await requestPVE(`/nodes/${userIsoConfig.node}/storage/${userIsoConfig.storage}/content?content=iso`, "GET", { token: pveAPIToken })).data.data;
const userIsos = [];

View File

@ -16,7 +16,7 @@ export async function checkAuth (cookies, res, vmpath = null) {
const db = global.db;
let auth = false;
if (db.getUserConfig(cookies.username) === null) {
if (db.getUser(cookies.username) === null) {
auth = false;
res.status(401).send({ auth, path: vmpath ? `${vmpath}/config` : "/version", error: `User ${cookies.username} not found in localdb.` });
res.end();
@ -47,9 +47,9 @@ export async function checkAuth (cookies, res, vmpath = null) {
*/
export async function getUserResources (req, username) {
const db = global.db;
const dbResources = db.getGlobalConfig().resources;
const dbResources = db.getGlobal().resources;
const used = await getUsedResources(req, dbResources);
const userResources = db.getUserConfig(username).resources;
const userResources = db.getUser(username).resources;
Object.keys(userResources).forEach((k) => {
if (dbResources[k] && dbResources[k].type === "list") {
userResources[k].forEach((listResource) => {
@ -79,7 +79,7 @@ export async function getUserResources (req, username) {
*/
export async function approveResources (req, username, request) {
const db = global.db;
const dbResources = db.getGlobalConfig().resources;
const dbResources = db.getGlobal().resources;
const userResources = await getUserResources(req, username);
let approved = true;
Object.keys(request).forEach((key) => {