6 Commits
Author SHA1 Message Date
alu e1c1de3fee move mv-isos and ct-templates paths to /access/users/:username/...
tronnet/workflows: Code Style -- Web Components / style-web (push) Successful in 16s
2026-09-14 19:00:46 +00:00
alu 4731b699c2 fix example network unit in template.config,json 2026-08-26 21:00:12 +00:00
alu 4557586e88 fix linting issue
tronnet/workflows: Code Style -- Web Components / style-web (push) Successful in 15s
2026-08-26 20:56:52 +00:00
alu da92ce9ea0 swap access-amanger-api backend to json request encoding
tronnet/workflows: Code Style -- Web Components / style-web (push) Successful in 17s
2026-08-20 20:20:52 +00:00
alu be82519d80 move api tests 2026-08-18 22:59:10 +00:00
alu 54c1fe846e fix possible bug when access-manager-api resource name is mismatched with api config
tronnet/workflows: Code Style -- Web Components / style-web (push) Successful in 15s
2026-08-11 23:49:59 +00:00
9 changed files with 92 additions and 126 deletions
+1 -1
View File
@@ -3,4 +3,4 @@
**/localdb.json
**/docs
**/config.json
.vscode/settings.json
.vscode/*
-18
View File
@@ -1,18 +0,0 @@
### Get ticket
POST {{baseUrl}}/access/ticket
Content-Type: application/x-www-form-urlencoded
username={{username}}
&password={{password}}
### Get user
GET {{baseUrl}}/access/users/{{username}}
### Get group
GET {{baseUrl}}/access/groups/{{groupname}}
### Get all pools
GET {{baseUrl}}/access/pools/
### Get pool
GET {{baseUrl}}/access/pools/{{poolname}}
-36
View File
@@ -1,36 +0,0 @@
### Get ticket
POST {{baseUrl}}/access/ticket
Content-Type: application/x-www-form-urlencoded
username={{username}}
&password={{password}}
### Get instance resources
GET {{baseUrl}}/cluster/{{testvmpath}}
### Get instance backups
GET {{baseUrl}}/cluster/{{testvmpath}}/backup
### Test create instance
POST {{baseUrl}}/cluster/{{testvmpath}}/create
Content-Type: application/x-www-form-urlencoded
name=testvm
&pool={{poolname}}
&cores=8
&memory=8192
### Test fail create instance
POST {{baseUrl}}/cluster/{{testvmpath}}/create
Content-Type: application/x-www-form-urlencoded
name=testvm
&pool={{poolname}}
&cores=9999
&memory=8192
### Test delete instance
DELETE {{baseUrl}}/cluster/{{testvmpath}}/delete
-2
View File
@@ -1,2 +0,0 @@
### Get version
GET {{baseUrl}}/version
+1 -1
View File
@@ -117,7 +117,7 @@
"multiplier": 1000000,
"base": 1000,
"compact": true,
"unit": "B/s",
"unit": "b/s",
"display": true,
"category": ""
},
+1 -1
View File
@@ -25,7 +25,7 @@ export default class ACCESS_MANAGER_API extends ACCESS_BACKEND {
mode: "cors",
credentials: "include",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
"Content-Type": "application/json"
},
data: body
};
+79
View File
@@ -1,6 +1,9 @@
import { Router } from "express";
export const router = Router({ mergeParams: true });
const config = global.config;
const checkAuth = global.utils.checkAuth;
/**
* GET - get specific user
* request:
@@ -35,3 +38,79 @@ router.get("/:username", async (req, res) => {
res.status(200).send({ user });
});
/**
* GET - get user accessible iso files
* response:
* - 200: Array.<Object>
* - 401: {auth: false}
*/
router.get("/:username/vm-isos", async (req, res) => {
const params = {
username: req.params.username
};
// check auth
const auth = await checkAuth(req.cookies, res);
if (!auth) {
return;
}
// check requested username is current user
if (req.cookies.username !== params.username) {
res.status(401).send({ auth: false });
return;
}
// get user iso config
const userIsoConfig = config.useriso;
// get all isos
const content = await global.pve.requestPVE(`/nodes/${userIsoConfig.node}/storage/${userIsoConfig.storage}/content?content=iso`, "GET", { token: true });
if (content.status !== 200) {
res.status(content.status).send({ error: content.statusText });
return;
}
const isos = content.data;
const userIsos = [];
isos.forEach((iso) => {
iso.name = iso.volid.replace(`${userIsoConfig.storage}:iso/`, "");
userIsos.push(iso);
});
userIsos.sort();
res.status(200).send(userIsos);
});
/**
* GET - get user accessible container template files
* response:
* - 200: Array.<Object>
* - 401: {auth: false}
*/
router.get("/:username/ct-templates", async (req, res) => {
const params = {
username: req.params.username
};
// check auth
const auth = await checkAuth(req.cookies, res);
if (!auth) {
return;
}
// check requested username is current user
if (req.cookies.username !== params.username) {
res.status(401).send({ auth: false });
return;
}
// get user iso config
const userIsoConfig = config.useriso;
// get all isos
const content = await global.pve.requestPVE(`/nodes/${userIsoConfig.node}/storage/${userIsoConfig.storage}/content?content=vztmpl`, "GET", { token: true });
if (content.status !== 200) {
res.status(content.status).send({ error: content.statusText });
return;
}
const isos = content.data;
const userIsos = [];
isos.forEach((iso) => {
iso.name = iso.volid.replace(`${userIsoConfig.storage}:vztmpl/`, "");
userIsos.push(iso);
});
userIsos.sort();
res.status(200).send(userIsos);
});
-65
View File
@@ -1,65 +0,0 @@
import { Router } from "express";
export const router = Router({ mergeParams: true }); ;
const config = global.config;
const checkAuth = global.utils.checkAuth;
/**
* GET - get user accessible iso files
* response:
* - 200: Array.<Object>
* - 401: {auth: false}
*/
router.get("/vm-isos", async (req, res) => {
// check auth
const auth = await checkAuth(req.cookies, res);
if (!auth) {
return;
}
// get user iso config
const userIsoConfig = config.useriso;
// get all isos
const content = await global.pve.requestPVE(`/nodes/${userIsoConfig.node}/storage/${userIsoConfig.storage}/content?content=iso`, "GET", { token: true });
if (content.status !== 200) {
res.status(content.status).send({ error: content.statusText });
return;
}
const isos = content.data;
const userIsos = [];
isos.forEach((iso) => {
iso.name = iso.volid.replace(`${userIsoConfig.storage}:iso/`, "");
userIsos.push(iso);
});
userIsos.sort();
res.status(200).send(userIsos);
});
/**
* GET - get user accessible container template files
* response:
* - 200: Array.<Object>
* - 401: {auth: false}
*/
router.get("/ct-templates", async (req, res) => {
// check auth
const auth = await checkAuth(req.cookies, res);
if (!auth) {
return;
}
// get user iso config
const userIsoConfig = config.useriso;
// get all isos
const content = await global.pve.requestPVE(`/nodes/${userIsoConfig.node}/storage/${userIsoConfig.storage}/content?content=vztmpl`, "GET", { token: true });
if (content.status !== 200) {
res.status(content.status).send({ error: content.statusText });
return;
}
const isos = content.data;
const userIsos = [];
isos.forEach((iso) => {
iso.name = iso.volid.replace(`${userIsoConfig.storage}:vztmpl/`, "");
userIsos.push(iso);
});
userIsos.sort();
res.status(200).send(userIsos);
});
+10 -2
View File
@@ -4,6 +4,7 @@ import url from "url";
import * as fs from "fs";
import { readFileSync } from "fs";
import { exit } from "process";
import { log } from "console";
/**
* Check if a user is authorized to access a specified vm, or the cluster in general.
@@ -76,7 +77,7 @@ export async function getPoolResources (req, pool) {
// setup the pool resource object with used and avail for each resource and each resource pool
// also add a total counter for each resource (only used for display, not used to check requests)
for (const resourceName of Object.keys(poolConfigResources)) {
if (configResources[resourceName].type === "list") {
if (resourceName in configResources && configResources[resourceName].type === "list") {
poolConfigResources[resourceName].total = [];
poolConfigResources[resourceName].global.forEach((e) => {
e.used = 0;
@@ -105,7 +106,7 @@ export async function getPoolResources (req, pool) {
});
}
}
else {
else if (resourceName in configResources){ // numeric or storage
const total = {
max: 0,
used: 0,
@@ -123,6 +124,13 @@ export async function getPoolResources (req, pool) {
}
poolConfigResources[resourceName].total = total;
}
else {
// pool's resource config included a resource which was not in the metadata config
// delete it from the config
// remeber that a resource requested with no config limit is default deny
delete poolConfigResources[resourceName];
console.log(`utils: pool had resource key ${resourceName} which is not in the config.json`);
}
}
const resources = await global.pve.getPoolResources(req.cookies, pool);