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": { "useriso": {
"node": "examplenode1", "node": "examplenode1",
"storage": "cephfs" "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": { "users": {

View File

@ -7,12 +7,12 @@ class LocalDB {
constructor (path) { constructor (path) {
try { try {
this.#path = path; this.#path = path;
this.load(); this.#load();
this.pveAPI = this.getGlobalConfig().application.pveAPI; this.pveAPI = this.getConfig().application.pveAPI;
this.pveAPIToken = this.getGlobalConfig().application.pveAPIToken; this.pveAPIToken = this.getConfig().application.pveAPIToken;
this.listenPort = this.getGlobalConfig().application.listenPort; this.listenPort = this.getConfig().application.listenPort;
this.hostname = this.getGlobalConfig().application.hostname; this.hostname = this.getConfig().application.hostname;
this.domain = this.getGlobalConfig().application.domain; this.domain = this.getConfig().application.domain;
} }
catch { catch {
console.log(`Error: ${path} was not found. Please follow the directions in the README to initialize localdb.json.`); console.log(`Error: ${path} was not found. Please follow the directions in the README to initialize localdb.json.`);
@ -21,35 +21,64 @@ 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)); 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)); writeFileSync(this.#path, JSON.stringify(this.#data));
} }
/** getGlobal () {
* Gets the global config object from db.
* @returns {Object} global config data.
*/
getGlobalConfig () {
return this.#data.global; return this.#data.global;
} }
/** setGloal (config) {
* Gets a specific user's config from db. this.#data.global = config;
* @param {string} username of user to get config. this.#save();
* @returns {Object} specific user config data. }
*/
getUserConfig (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]; 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;
}
}
} }
export default LocalDB; export default LocalDB;

View File

@ -37,7 +37,7 @@ router.get(`/:node(${nodeRegexP})/pci`, async (req, res) => {
if (!auth) { if (!auth) {
return; return;
} }
const userNodes = db.getUserConfig(req.cookies.username).nodes; const userNodes = db.getUser(req.cookies.username).nodes;
if (!userNodes.includes(params.node)) { if (!userNodes.includes(params.node)) {
res.status(401).send({ auth: false, path: params.node }); res.status(401).send({ auth: false, path: params.node });
res.end(); res.end();
@ -164,7 +164,7 @@ router.post(`${basePath}/create`, async (req, res) => {
return; return;
} }
// get user db config // 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 vmid = Number.parseInt(params.vmid);
const vmidMin = user.cluster.vmid.min; const vmidMin = user.cluster.vmid.min;
const vmidMax = user.cluster.vmid.max; 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 // 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 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))) { 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.status(500).send({ error: `Requested target ${params.disk} is not in allowed list [${resourceConfig[diskConfig.storage].disks}].` });
res.end(); res.end();
@ -337,7 +337,7 @@ router.post("/:disk/create", async (req, res) => {
return; return;
} }
// target disk must be allowed according to storage options // 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))) { 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.status(500).send({ error: `Requested target ${params.disk} is not in allowed list [${resourceConfig[params.storage].disks}].` });
res.end(); res.end();

View File

@ -63,7 +63,7 @@ router.post("/:netid/create", async (req, res) => {
return; return;
} }
// setup action // 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 = {}; let action = {};
if (params.type === "lxc") { 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}`; 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[`hostpci${params.hostpci}`] = `${params.device},pcie=${params.pcie}`;
action = JSON.stringify(action); action = JSON.stringify(action);
// commit 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)) { if (!(rootauth.status === 200)) {
res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." }); res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." });
res.end(); res.end();
@ -206,7 +206,7 @@ router.post("/create", async (req, res) => {
action[`hostpci${hostpci}`] = `${params.device},pcie=${params.pcie}`; action[`hostpci${hostpci}`] = `${params.device},pcie=${params.pcie}`;
action = JSON.stringify(action); action = JSON.stringify(action);
// commit 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)) { if (!(rootauth.status === 200)) {
res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." }); res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." });
res.end(); res.end();
@ -263,7 +263,7 @@ router.delete("/:hostpci/delete", async (req, res) => {
// setup action // setup action
const action = JSON.stringify({ delete: `hostpci${params.hostpci}` }); 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 // 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)) { if (!(rootauth.status === 200)) {
res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." }); res.status(rootauth.status).send({ auth: false, error: "API could not authenticate as root user." });
res.end(); res.end();

View File

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

View File

@ -24,8 +24,8 @@ let prevState = {};
// target ms value // target ms value
let targetMSTime = null; let targetMSTime = null;
const schemes = db.getGlobalConfig().clientsync.schemes; const schemes = db.getGlobal().clientsync.schemes;
const resourceTypes = db.getGlobalConfig().clientsync.resourcetypes; const resourceTypes = db.getGlobal().clientsync.resourcetypes;
/** /**
* GET - get list of supported synchronization schemes * GET - get list of supported synchronization schemes
* responses: * responses:
@ -164,7 +164,7 @@ if (schemes.interrupt.enabled) {
} }
else { else {
wsServer.handleUpgrade(req, socket, head, (socket) => { 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); 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"]; const allowKeys = ["resources", "cluster", "nodes"];
if (allowKeys.includes(params.key)) { 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]); res.status(200).send(config[params.key]);
} }
else { else {
@ -64,7 +64,7 @@ router.get("/iso", async (req, res) => {
return; return;
} }
// get user iso config // get user iso config
const userIsoConfig = db.getGlobalConfig().useriso; const userIsoConfig = db.getGlobal().useriso;
// get all isos // get all isos
const isos = (await requestPVE(`/nodes/${userIsoConfig.node}/storage/${userIsoConfig.storage}/content?content=iso`, "GET", { token: pveAPIToken })).data.data; const isos = (await requestPVE(`/nodes/${userIsoConfig.node}/storage/${userIsoConfig.storage}/content?content=iso`, "GET", { token: pveAPIToken })).data.data;
const userIsos = []; const userIsos = [];

View File

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