initial updates to api v2.0.0:
- switch access backend to access-manager-api - change resource quota to pool based - simplify backend system - various cleanup
This commit is contained in:
1 parent
cf47cf6c71
commit
24ed6907c7
26 files changed
+708
-1055
No files matched your search
@@ -64,12 +64,7 @@ router.post("/ticket", async (req, res) => {
|
||||
|
||||
const domain = global.config.application.domain;
|
||||
const userObj = global.utils.getUserObjFromUsername(params.username);
|
||||
let backends = global.userManager.getBackendsByUser(userObj);
|
||||
if (backends == null) {
|
||||
res.status(401).send({ auth: false, error: `${params.username} not found in any ProxmoxAAS backends` });
|
||||
return;
|
||||
}
|
||||
backends = backends.concat(["pve"]);
|
||||
const backends = [global.config.handlers.users, global.config.handlers.instance];
|
||||
const cm = new CookieFetcher();
|
||||
const error = await cm.fetchBackends(backends, userObj, params.password);
|
||||
if (error) {
|
||||
@@ -107,7 +102,7 @@ router.delete("/ticket", async (req, res) => {
|
||||
res.cookie(cookie, "", { domain, path: "/", expires: expire, secure: true, sameSite: "none" });
|
||||
}
|
||||
await global.pve.closeSession(req.cookies);
|
||||
await global.userManager.closeSession(req.cookies);
|
||||
await global.access.closeSession(req.cookies);
|
||||
res.status(200).send({ auth: false });
|
||||
});
|
||||
|
||||
@@ -134,6 +129,6 @@ router.post("/password", async (req, res) => {
|
||||
const newAttributes = {
|
||||
userpassword: params.password
|
||||
};
|
||||
const response = await global.userManager.setUser(userObj, newAttributes, req.cookies);
|
||||
const response = await global.access.setUser(userObj, newAttributes, req.cookies);
|
||||
res.status(response.status).send(response);
|
||||
});
|
||||
@@ -3,22 +3,6 @@ export const router = Router({ mergeParams: true });
|
||||
|
||||
const checkAuth = global.utils.checkAuth;
|
||||
|
||||
/**
|
||||
* GET - get all groups
|
||||
* responses:
|
||||
* - 200: {auth: true, groups: Array}
|
||||
* - 401: {auth: false}
|
||||
*/
|
||||
router.get("/", async (req, res) => {
|
||||
// check auth
|
||||
const auth = await checkAuth(req.cookies, res);
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
const groups = await global.userManager.getAllGroups(req.cookies);
|
||||
res.status(200).send({ groups });
|
||||
});
|
||||
|
||||
/**
|
||||
* GET - get specific group
|
||||
* request:
|
||||
@@ -36,6 +20,14 @@ router.get("/:groupname", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
const group = await global.userManager.getGroup(params.groupname, req.cookies);
|
||||
|
||||
const groupObj = global.utils.getGroupObjFromGroupname(params.groupname);
|
||||
const g = await global.access.getGroup(groupObj, req.cookies);
|
||||
if (g.ok !== true) {
|
||||
res.status(g.status).send(g);
|
||||
return;
|
||||
}
|
||||
const group = g.group;
|
||||
|
||||
res.status(200).send({ group });
|
||||
});
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Router } from "express";
|
||||
export const router = Router({ mergeParams: true });
|
||||
|
||||
const checkAuth = global.utils.checkAuth;
|
||||
const checkUserInPool = global.utils.checkUserInPool;
|
||||
|
||||
/**
|
||||
* GET - get all available cluster pools
|
||||
* returns only pool IDs
|
||||
* responses:
|
||||
* - 200: List of pools
|
||||
* - PVE error
|
||||
*/
|
||||
router.get("/", async (req, res) => {
|
||||
// check auth
|
||||
const auth = await checkAuth(req.cookies, res);
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
||||
const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
|
||||
|
||||
const pools = {};
|
||||
|
||||
const poolnames = await global.pve.requestPVE("/pools", "GET", { token: true });
|
||||
|
||||
for (const poolpartial of poolnames.data) {
|
||||
const poolname = poolpartial.poolid;
|
||||
|
||||
const p = await global.access.getPool(poolname, req.cookies);
|
||||
if (p.ok !== true) {
|
||||
continue;
|
||||
}
|
||||
const pool = p.pool;
|
||||
|
||||
if (checkUserInPool(pool, userObj)) {
|
||||
const resources = await global.utils.getPoolResources(req, poolname);
|
||||
pool.resources = resources;
|
||||
pools[poolname] = pool;
|
||||
}
|
||||
}
|
||||
|
||||
res.status(200).send({ pools });
|
||||
res.end();
|
||||
});
|
||||
|
||||
/**
|
||||
* GET - get specific pool
|
||||
* request:
|
||||
* - poolname: name of pool to get
|
||||
* responses:
|
||||
* - 200: {auth: true, pool: Object}
|
||||
* - 401: {auth: false}
|
||||
*/
|
||||
router.get("/:poolname", async (req, res) => {
|
||||
const params = {
|
||||
poolname: req.params.poolname
|
||||
};
|
||||
// check auth
|
||||
const auth = await checkAuth(req.cookies, res);
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
||||
const p = await global.access.getPool(params.poolname, req.cookies);
|
||||
if (p.ok !== true) {
|
||||
res.status(p.status).send(p);
|
||||
return;
|
||||
}
|
||||
const pool = p.pool;
|
||||
const resources = await global.utils.getPoolResources(req, params.poolname);
|
||||
|
||||
pool.resources = resources;
|
||||
|
||||
res.status(200).send({ pool });
|
||||
});
|
||||
@@ -3,22 +3,6 @@ export const router = Router({ mergeParams: true });
|
||||
|
||||
const checkAuth = global.utils.checkAuth;
|
||||
|
||||
/**
|
||||
* GET - get all users
|
||||
* responses:
|
||||
* - 200: {auth:true, users: Array}
|
||||
* - 401: {auth: false}
|
||||
*/
|
||||
router.get("/", async (req, res) => {
|
||||
// check auth
|
||||
const auth = await checkAuth(req.cookies, res);
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
const users = await global.userManager.getAllUsers(req.cookies);
|
||||
res.status(200).send({ users });
|
||||
});
|
||||
|
||||
/**
|
||||
* GET - get specific user
|
||||
* request:
|
||||
@@ -36,7 +20,14 @@ router.get("/:username", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
||||
const userObj = global.utils.getUserObjFromUsername(params.username);
|
||||
const user = await global.userManager.getUser(userObj, req.cookies);
|
||||
const u = await global.access.getUser(userObj, req.cookies);
|
||||
if (u.ok !== true) {
|
||||
res.status(u.status).send(u);
|
||||
return;
|
||||
}
|
||||
const user = u.user;
|
||||
|
||||
res.status(200).send({ user });
|
||||
});
|
||||
+21
-47
@@ -3,7 +3,8 @@ export const router = Router({ mergeParams: true });
|
||||
|
||||
const checkAuth = global.utils.checkAuth;
|
||||
const approveResources = global.utils.approveResources;
|
||||
const getUserResources = global.utils.getUserResources;
|
||||
const getPoolResources = global.utils.getPoolResources;
|
||||
const checkUserInPool = global.utils.checkUserInPool;
|
||||
|
||||
const nodeRegexP = "[\\w-]+";
|
||||
const typeRegexP = "qemu|lxc";
|
||||
@@ -13,33 +14,6 @@ const basePath = `/:node(${nodeRegexP})/:type(${typeRegexP})/:vmid(${vmidRegexP}
|
||||
|
||||
global.utils.recursiveImportRoutes(router, basePath, "cluster", import.meta.url);
|
||||
|
||||
/**
|
||||
* GET - get all available cluster pools
|
||||
* returns only pool IDs
|
||||
* responses:
|
||||
* - 200: List of pools
|
||||
* - PVE error
|
||||
*/
|
||||
router.get("/pools", async (req, res) => {
|
||||
// check auth
|
||||
const auth = await checkAuth(req.cookies, res);
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
||||
const allPools = await global.pve.requestPVE("/pools", "GET", { token: true });
|
||||
|
||||
if (allPools.status === 200) {
|
||||
const allPoolsIDs = Array.from(allPools.data.data, (x) => x.poolid);
|
||||
res.status(allPools.status).send({ pools: allPoolsIDs });
|
||||
res.end();
|
||||
}
|
||||
else {
|
||||
res.status(allPools.status).send({ error: allPools.statusText });
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET - get all available cluster nodes
|
||||
* uses existing user permissions without elevation
|
||||
@@ -58,7 +32,7 @@ router.get("/nodes", async (req, res) => {
|
||||
const allNodes = await global.pve.requestPVE("/nodes", "GET", { cookies: req.cookies });
|
||||
|
||||
if (allNodes.status === 200) {
|
||||
const allNodesIDs = Array.from(allNodes.data.data, (x) => x.node);
|
||||
const allNodesIDs = Array.from(allNodes.data, (x) => x.node);
|
||||
res.status(allNodes.status).send({ nodes: allNodesIDs });
|
||||
res.end();
|
||||
}
|
||||
@@ -89,7 +63,7 @@ router.get(`/:node(${nodeRegexP})/pci`, async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
const userNodes = (await global.userManager.getUser(userObj, req.cookies)).cluster.nodes;
|
||||
const userNodes = (await global.access.getPool(userObj, req.cookies)).cluster.nodes;
|
||||
if (userNodes[params.node] !== true) { // user does not have access to the node
|
||||
res.status(401).send({ auth: false, path: params.node });
|
||||
res.end();
|
||||
@@ -97,7 +71,7 @@ router.get(`/:node(${nodeRegexP})/pci`, async (req, res) => {
|
||||
}
|
||||
|
||||
// get remaining user resources
|
||||
const userAvailPci = (await getUserResources(req, userObj)).pci.nodes[params.node]; // we assume that the node list is used. TODO support global lists
|
||||
const userAvailPci = (await getPoolResources(req, userObj)).pci.nodes[params.node]; // we assume that the node list is used. TODO support global lists
|
||||
if (userAvailPci === undefined) { // user has no available devices on this node, so send an empty list
|
||||
res.status(200).send([]);
|
||||
res.end();
|
||||
@@ -201,7 +175,7 @@ router.post(`${basePath}/resources`, async (req, res) => {
|
||||
request.cpu = params.proctype;
|
||||
}
|
||||
// check resource approval
|
||||
const { approved, reason } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved, reason } = await approveResources(req, userObj, params.node, instance.pool, request);
|
||||
if (!approved) {
|
||||
res.status(400).send({ request, error: "Not enough resources to satisfy request.", reason });
|
||||
res.end();
|
||||
@@ -269,11 +243,11 @@ router.post(`${basePath}/create`, async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
// get user db config
|
||||
const user = await global.userManager.getUser(userObj, req.cookies);
|
||||
// get pool config
|
||||
const pool = (await global.access.getPool(params.pool, req.cookies)).pool;
|
||||
const vmid = Number.parseInt(params.vmid);
|
||||
const vmidMin = user.cluster.vmid.min;
|
||||
const vmidMax = user.cluster.vmid.max;
|
||||
const vmidMin = pool["vmid-allowed"].min;
|
||||
const vmidMax = pool["vmid-allowed"].max;
|
||||
// check vmid is within allowed range
|
||||
if (vmid < vmidMin || vmid > vmidMax) {
|
||||
res.status(500).send({ error: `Requested vmid ${vmid} is out of allowed range [${vmidMin},${vmidMax}].` });
|
||||
@@ -281,14 +255,14 @@ router.post(`${basePath}/create`, async (req, res) => {
|
||||
return;
|
||||
}
|
||||
// check node is within allowed list
|
||||
if (user.cluster.nodes[params.node] !== true) {
|
||||
res.status(500).send({ error: `Requested node ${params.node} is not in allowed nodes [${user.cluster.nodes}].` });
|
||||
if (pool["nodes-allowed"][params.node] !== true) {
|
||||
res.status(500).send({ error: `Requested node ${params.node} is not in allowed nodes [${pool["nodes-allowed"]}].` });
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
// check if pool is in user allowed pools
|
||||
if (user.cluster.pools[params.pool] !== true) {
|
||||
res.status(500).send({ error: `Requested pool ${params.pool} not in allowed pools [${user.pools}]` });
|
||||
// check if user is in pool
|
||||
if(checkUserInPool(pool, userObj) !== true) {
|
||||
res.status(500).send({ error: `Requested pool ${params.pool} does not contain user ${req.cookies.username}]` });
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
@@ -301,9 +275,9 @@ router.post(`${basePath}/create`, async (req, res) => {
|
||||
request.swap = Number(params.swap) * 1024 ** 2;
|
||||
request[params.rootfslocation] = params.rootfssize * 1024 ** 3;
|
||||
}
|
||||
for (const key of Object.keys(user.templates.instances[params.type])) {
|
||||
const item = user.templates.instances[params.type][key];
|
||||
if (item.resource) {
|
||||
for (const key of Object.keys(pool.templates.instances[params.type])) {
|
||||
const item = pool.templates.instances[params.type][key];
|
||||
if (item.resource.enabled) {
|
||||
if (request[item.resource.name]) {
|
||||
request[item.resource.name] += item.resource.amount;
|
||||
}
|
||||
@@ -313,7 +287,7 @@ router.post(`${basePath}/create`, async (req, res) => {
|
||||
}
|
||||
}
|
||||
// check resource approval
|
||||
const { approved, reason } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved, reason } = await await approveResources(req, userObj, params.node, params.pool, request);
|
||||
if (!approved) {
|
||||
res.status(400).send({ request, error: "Not enough resources to satisfy request.", reason });
|
||||
res.end();
|
||||
@@ -326,8 +300,8 @@ router.post(`${basePath}/create`, async (req, res) => {
|
||||
memory: Number(params.memory),
|
||||
pool: params.pool
|
||||
};
|
||||
for (const key of Object.keys(user.templates.instances[params.type])) {
|
||||
action[key] = user.templates.instances[params.type][key].value;
|
||||
for (const key of Object.keys(pool.templates.instances[params.type])) {
|
||||
action[key] = pool.templates.instances[params.type][key].value;
|
||||
}
|
||||
if (params.type === "lxc") {
|
||||
action.swap = params.swap;
|
||||
|
||||
@@ -33,7 +33,7 @@ router.get("/", async (req, res) => {
|
||||
const storage = global.config.backups.storage;
|
||||
const backups = await global.pve.requestPVE(`/nodes/${params.node}/storage/${storage}/content?content=backup&vmid=${params.vmid}`, "GET", { token: true });
|
||||
if (backups.status === 200) {
|
||||
res.status(backups.status).send(backups.data.data);
|
||||
res.status(backups.status).send(backups.data);
|
||||
}
|
||||
else {
|
||||
res.status(backups.status).send({ error: backups.statusText });
|
||||
@@ -72,9 +72,9 @@ router.post("/", async (req, res) => {
|
||||
// check if number of backups is less than the allowed number
|
||||
const storage = global.config.backups.storage;
|
||||
const backups = await global.pve.requestPVE(`/nodes/${params.node}/storage/${storage}/content?content=backup&vmid=${params.vmid}`, "GET", { token: true });
|
||||
const numBackups = backups.data.data.length;
|
||||
const numBackups = backups.data.length;
|
||||
const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
|
||||
const maxAllowed = (await global.userManager.getUser(userObj, req.cookies)).cluster.backups.max;
|
||||
const maxAllowed = (await global.access.getUser(userObj, req.cookies)).cluster.backups.max;
|
||||
if (backups.status !== 200) {
|
||||
res.status(backups.status).send({ error: backups.statusText });
|
||||
return;
|
||||
@@ -94,7 +94,7 @@ router.post("/", async (req, res) => {
|
||||
"notes-template": params.notes
|
||||
};
|
||||
const result = await global.pve.requestPVE(`/nodes/${params.node}/vzdump`, "POST", { token: true }, body);
|
||||
res.status(result.status).send(result.data.data);
|
||||
res.status(result.status).send(result.data);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -136,7 +136,7 @@ router.post("/notes", async (req, res) => {
|
||||
return;
|
||||
}
|
||||
let found = false;
|
||||
for (const volume of backups.data.data) {
|
||||
for (const volume of backups.data) {
|
||||
if (volume.subtype === params.type && String(volume.vmid) === params.vmid && volume.content === "backup" && volume.volid === params.volid) {
|
||||
found = true;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ router.delete("/", async (req, res) => {
|
||||
return;
|
||||
}
|
||||
let found = false;
|
||||
for (const volume of backups.data.data) {
|
||||
for (const volume of backups.data) {
|
||||
if (volume.subtype === params.type && String(volume.vmid) === params.vmid && volume.content === "backup" && volume.volid === params.volid) {
|
||||
found = true;
|
||||
}
|
||||
@@ -208,7 +208,7 @@ router.delete("/", async (req, res) => {
|
||||
|
||||
// found a valid backup with matching vmid and volid
|
||||
const result = await global.pve.requestPVE(`/nodes/${params.node}/storage/${storage}/content/${params.volid}?delay=5`, "DELETE", { token: true });
|
||||
res.status(result.status).send(result.data.data);
|
||||
res.status(result.status).send(result.data);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -248,7 +248,7 @@ router.post("/restore", async (req, res) => {
|
||||
return;
|
||||
}
|
||||
let found = false;
|
||||
for (const volume of backups.data.data) {
|
||||
for (const volume of backups.data) {
|
||||
if (volume.subtype === params.type && String(volume.vmid) === params.vmid && volume.content === "backup" && volume.volid === params.volid) {
|
||||
found = true;
|
||||
}
|
||||
@@ -281,7 +281,6 @@ router.post("/restore", async (req, res) => {
|
||||
}
|
||||
|
||||
const result = await global.pve.requestPVE(`/nodes/${params.node}/${params.type}/`, "POST", { token: true }, body);
|
||||
console.log(result);
|
||||
if (result.status === 200) {
|
||||
res.status(result.status).send();
|
||||
}
|
||||
|
||||
@@ -145,6 +145,8 @@ router.post("/:disk/resize", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
// get instance config for pool membership
|
||||
const instance = await global.pve.getInstance(params.node, params.vmid);
|
||||
// check disk existence
|
||||
const disk = await global.pve.getDisk(params.node, params.vmid, params.disk); // get target disk
|
||||
if (!disk) { // exit if disk does not exist
|
||||
@@ -157,7 +159,7 @@ router.post("/:disk/resize", async (req, res) => {
|
||||
const request = {};
|
||||
request[storage] = Number(params.size * 1024 ** 3); // setup request object
|
||||
// check request approval
|
||||
const { approved } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved } = await approveResources(req, userObj, params.node, instance.pool, request);
|
||||
if (!approved) {
|
||||
res.status(500).send({ request, error: `Storage ${storage} could not fulfill request of size ${params.size}G.` });
|
||||
res.end();
|
||||
@@ -205,6 +207,8 @@ router.post("/:disk/move", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
// get instance config for pool membership
|
||||
const instance = await global.pve.getInstance(params.node, params.vmid);
|
||||
// check disk existence
|
||||
const disk = await global.pve.getDisk(params.node, params.vmid, params.disk); // get target disk
|
||||
if (!disk) { // exit if disk does not exist
|
||||
@@ -220,7 +224,7 @@ router.post("/:disk/move", async (req, res) => {
|
||||
request[dstStorage] = Number(size); // always decrease destination storage by size
|
||||
}
|
||||
// check request approval
|
||||
const { approved } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved } = await approveResources(req, userObj, params.node, instance.pool, request);
|
||||
if (!approved) {
|
||||
res.status(500).send({ request, error: `Storage ${params.storage} could not fulfill request of size ${params.size}G.` });
|
||||
res.end();
|
||||
@@ -324,6 +328,8 @@ router.post("/:disk/create", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
// get instance config for pool membership
|
||||
const instance = await global.pve.getInstance(params.node, params.vmid);
|
||||
// disk must not exist
|
||||
const disk = await global.pve.getDisk(params.node, params.vmid, params.disk);
|
||||
if (disk) {
|
||||
@@ -337,7 +343,7 @@ router.post("/:disk/create", async (req, res) => {
|
||||
// setup request
|
||||
request[params.storage] = Number(params.size * 1024 ** 3);
|
||||
// check request approval
|
||||
const { approved } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved } = await approveResources(req, userObj, params.node, instance.pool, request);
|
||||
if (!approved) {
|
||||
res.status(500).send({ request, error: `Storage ${params.storage} could not fulfill request of size ${params.size}G.` });
|
||||
res.end();
|
||||
|
||||
@@ -36,6 +36,8 @@ router.post("/:netid/create", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
// get instance config for pool membership
|
||||
const instance = await global.pve.getInstance(params.node, params.vmid);
|
||||
// net interface must not exist
|
||||
const net = await global.pve.getNet(params.node, params.vmid, params.netid);
|
||||
if (net) {
|
||||
@@ -53,14 +55,14 @@ router.post("/:netid/create", async (req, res) => {
|
||||
};
|
||||
// check resource approval
|
||||
const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
|
||||
const { approved } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved } = await approveResources(req, userObj, params.node, instance.pool, request);
|
||||
if (!approved) {
|
||||
res.status(500).send({ request, error: `Could not fulfil network request of ${params.rate}MB/s.` });
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
// setup action
|
||||
const nc = (await global.userManager.getUser(userObj, req.cookies)).templates.network[params.type];
|
||||
const nc = (await global.access.getUser(userObj, req.cookies)).templates.network[params.type];
|
||||
const action = {};
|
||||
if (params.type === "lxc") {
|
||||
action[`${params.netid}`] = `name=${params.name},bridge=${nc.bridge},ip=${nc.ip},ip6=${nc.ip6},tag=${nc.vlan},type=${nc.type},rate=${params.rate}`;
|
||||
@@ -105,6 +107,8 @@ router.post("/:netid/modify", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
// get instance config for pool membership
|
||||
const instance = await global.pve.getInstance(params.node, params.vmid);
|
||||
// net interface must already exist
|
||||
const net = await global.pve.getNet(params.node, params.vmid, params.netid);
|
||||
if (!net) {
|
||||
@@ -117,7 +121,7 @@ router.post("/:netid/modify", async (req, res) => {
|
||||
};
|
||||
// check resource approval
|
||||
const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
|
||||
const { approved } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved } = await approveResources(req, userObj, params.node, instance.pool, request);
|
||||
if (!approved) {
|
||||
res.status(500).send({ request, error: `Could not fulfil network request of ${params.rate}MB/s.` });
|
||||
res.end();
|
||||
|
||||
@@ -78,6 +78,8 @@ router.post("/:hostpci/modify", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
// get instance config for pool membership
|
||||
const instance = await global.pve.getInstance(params.node, params.vmid);
|
||||
// force all functions
|
||||
params.device = params.device.split(".")[0];
|
||||
// device must exist to be modified
|
||||
@@ -100,7 +102,7 @@ router.post("/:hostpci/modify", async (req, res) => {
|
||||
return;
|
||||
}
|
||||
// check resource approval
|
||||
const { approved } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved } = await approveResources(req, userObj, params.node, instance.pool, request);
|
||||
if (!approved) {
|
||||
res.status(500).send({ request, error: `Could not fulfil request for ${requestedDevice.device_name}.` });
|
||||
res.end();
|
||||
@@ -158,6 +160,8 @@ router.post("/:hostpci/create", async (req, res) => {
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
// get instance config for pool membership
|
||||
const instance = await global.pve.getInstance(params.node, params.vmid);
|
||||
// force all functions
|
||||
params.device = params.device.split(".")[0];
|
||||
// device must not exist to be added
|
||||
@@ -173,7 +177,7 @@ router.post("/:hostpci/create", async (req, res) => {
|
||||
const request = { pci: requestedDevice.device_name };
|
||||
// check resource approval
|
||||
const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
|
||||
const { approved } = await approveResources(req, userObj, request, params.node);
|
||||
const { approved } = await approveResources(req, userObj, params.node, instance.pool, request);
|
||||
if (!approved) {
|
||||
res.status(500).send({ request, error: `Could not fulfil request for ${requestedDevice.device_name}.` });
|
||||
res.end();
|
||||
|
||||
+5
-6
@@ -52,7 +52,7 @@ if (schemes.hash.enabled) {
|
||||
return;
|
||||
}
|
||||
// get current cluster resources - do not use fabric here because fabric is not always updated to changes like up/down state changes
|
||||
const status = (await global.pve.requestPVE("/cluster/resources", "GET", { cookies: req.cookies })).data.data;
|
||||
const status = (await global.pve.requestPVE("/cluster/resources", "GET", { cookies: req.cookies })).data;
|
||||
// filter out just state information of resources that are needed
|
||||
const state = extractClusterState(status, resourceTypes);
|
||||
res.status(200).send(getObjectHash(state));
|
||||
@@ -166,11 +166,10 @@ if (schemes.interrupt.enabled) {
|
||||
}
|
||||
else {
|
||||
wsServer.handleUpgrade(req, socket, head, async (socket) => {
|
||||
// get the user pools
|
||||
const userObj = global.utils.getUserObjFromUsername(cookies.username);
|
||||
const pools = Object.keys((await global.userManager.getUser(userObj, cookies)).cluster.pools);
|
||||
// use user cookies to determine which pools they can see, lazily assume that if a user can audit a pool they are also can audit pool member state
|
||||
const pools = await global.pve.requestPVE("/pools", "GET", { cookies });
|
||||
// emit the connection to initialize socket
|
||||
wsServer.emit("connection", socket, cookies.username, pools);
|
||||
wsServer.emit("connection", socket, cookies.username, Object.keys(pools.data));
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -190,7 +189,7 @@ if (schemes.interrupt.enabled) {
|
||||
return;
|
||||
}
|
||||
// get current cluster resources
|
||||
const status = (await global.pve.requestPVE("/cluster/resources", "GET", { token: true })).data.data;
|
||||
const status = (await global.pve.requestPVE("/cluster/resources", "GET", { token: true })).data;
|
||||
// filter out just state information of resources that are needed, and hash each one
|
||||
const currState = extractClusterState(status, resourceTypes, true);
|
||||
// get a map of users to send sync notifications
|
||||
|
||||
+2
-56
@@ -4,60 +4,6 @@ export const router = Router({ mergeParams: true }); ;
|
||||
const config = global.config;
|
||||
const checkAuth = global.utils.checkAuth;
|
||||
|
||||
/**
|
||||
* GET - get db user resource information including allocated, free, and maximum resource values along with resource metadata
|
||||
* responses:
|
||||
* - 200: {avail: Object, max: Object, used: Object, resources: Object}
|
||||
* - 401: {auth: false}
|
||||
*/
|
||||
router.get("/dynamic/resources", async (req, res) => {
|
||||
const params = {
|
||||
username: req.cookies.username
|
||||
};
|
||||
|
||||
// check auth
|
||||
const auth = await checkAuth(req.cookies, res);
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
|
||||
const userObj = global.utils.getUserObjFromUsername(params.username);
|
||||
|
||||
const resources = await global.utils.getUserResources(req, userObj);
|
||||
res.status(200).send(resources);
|
||||
});
|
||||
|
||||
/**
|
||||
* GET - get db user configuration by key
|
||||
* request:
|
||||
* - key: string - user config key
|
||||
* responses:
|
||||
* - 200: Object
|
||||
* - 401: {auth: false}
|
||||
* - 401: {auth: false, error: string}
|
||||
*/
|
||||
router.get("/config/:key", async (req, res) => {
|
||||
const params = {
|
||||
key: req.params.key
|
||||
};
|
||||
|
||||
const userObj = global.utils.getUserObjFromUsername(req.cookies.username);
|
||||
|
||||
// check auth
|
||||
const auth = await checkAuth(req.cookies, res);
|
||||
if (!auth) {
|
||||
return;
|
||||
}
|
||||
const allowKeys = ["resources", "cluster"];
|
||||
if (allowKeys.includes(params.key)) {
|
||||
const config = await global.userManager.getUser(userObj, req.cookies);
|
||||
res.status(200).send(config[params.key]);
|
||||
}
|
||||
else {
|
||||
res.status(401).send({ auth: false, error: `User is not authorized to access /user/config/${params.key}.` });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET - get user accessible iso files
|
||||
* response:
|
||||
@@ -78,7 +24,7 @@ router.get("/vm-isos", async (req, res) => {
|
||||
res.status(content.status).send({ error: content.statusText });
|
||||
return;
|
||||
}
|
||||
const isos = content.data.data;
|
||||
const isos = content.data;
|
||||
const userIsos = [];
|
||||
isos.forEach((iso) => {
|
||||
iso.name = iso.volid.replace(`${userIsoConfig.storage}:iso/`, "");
|
||||
@@ -108,7 +54,7 @@ router.get("/ct-templates", async (req, res) => {
|
||||
res.status(content.status).send({ error: content.statusText });
|
||||
return;
|
||||
}
|
||||
const isos = content.data.data;
|
||||
const isos = content.data;
|
||||
const userIsos = [];
|
||||
isos.forEach((iso) => {
|
||||
iso.name = iso.volid.replace(`${userIsoConfig.storage}:vztmpl/`, "");
|
||||
|
||||
Reference in new issue
Block a user