consolidate user config paths,
move global config values to global key in localdb
This commit is contained in:
parent
8e476ea352
commit
4fbb64745b
@ -22,7 +22,7 @@ In Proxmox VE, follow the following steps:
|
|||||||
## Installation - API
|
## Installation - API
|
||||||
1. Clone this repo onto `Client Host`
|
1. Clone this repo onto `Client Host`
|
||||||
2. Run `npm install` to initiaze the package requirements
|
2. Run `npm install` to initiaze the package requirements
|
||||||
3. Copy `localdb.json.template` as `localdb.json` and modify the following values under `pveAPIToken`:
|
3. Copy `template.localdb.json` as `localdb.json` and modify the following values under `pveAPIToken`:
|
||||||
- pveAPI - the URI to the Proxmox API, ie `<proxmoxhost>:8006/api2/json` or `<proxmox URL>/api2/json` if Proxmox VE is behind a reverse proxy.
|
- pveAPI - the URI to the Proxmox API, ie `<proxmoxhost>:8006/api2/json` or `<proxmox URL>/api2/json` if Proxmox VE is behind a reverse proxy.
|
||||||
- hostname - the ProxmoxAAS-Client URL, ie `host.domain.tld`
|
- hostname - the ProxmoxAAS-Client URL, ie `host.domain.tld`
|
||||||
- domain - the base domain for the client and proxmox, ie `domain.tld`
|
- domain - the base domain for the client and proxmox, ie `domain.tld`
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
{
|
|
||||||
"application": {
|
|
||||||
"pveAPI": "https://pve.mydomain.example/api2/json",
|
|
||||||
"pveAPIToken": {
|
|
||||||
"user": "proxmoxaas-api",
|
|
||||||
"realm": "pve",
|
|
||||||
"id": "token",
|
|
||||||
"uuid": "token-secret-value"
|
|
||||||
},
|
|
||||||
"pveroot": {
|
|
||||||
"username": "root@pam",
|
|
||||||
"password": "rootpassword"
|
|
||||||
},
|
|
||||||
"listenPort": 80,
|
|
||||||
"hostname": "client.mydomain.example",
|
|
||||||
"domain": "mydomain.example"
|
|
||||||
},
|
|
||||||
"resources": {
|
|
||||||
"cpu": {
|
|
||||||
"type": "list",
|
|
||||||
"whitelist": true,
|
|
||||||
"display": false
|
|
||||||
},
|
|
||||||
"cores": {
|
|
||||||
"type": "numeric",
|
|
||||||
"multiplier": 1,
|
|
||||||
"base": 1024,
|
|
||||||
"compact": false,
|
|
||||||
"unit": "Cores",
|
|
||||||
"display": true
|
|
||||||
},
|
|
||||||
"memory": {
|
|
||||||
"type": "numeric",
|
|
||||||
"multiplier": 1048576,
|
|
||||||
"base": 1024,
|
|
||||||
"compact": true,
|
|
||||||
"unit": "B",
|
|
||||||
"display": true
|
|
||||||
},
|
|
||||||
"swap": {
|
|
||||||
"type": "numeric",
|
|
||||||
"multiplier": 1048576,
|
|
||||||
"base": 1024,
|
|
||||||
"compact": true,
|
|
||||||
"unit": "B",
|
|
||||||
"display": true
|
|
||||||
},
|
|
||||||
"local": {
|
|
||||||
"type": "storage",
|
|
||||||
"multiplier": 1,
|
|
||||||
"base": 1024,
|
|
||||||
"compact": true,
|
|
||||||
"unit": "B",
|
|
||||||
"disks": [
|
|
||||||
"rootfs",
|
|
||||||
"mp",
|
|
||||||
"sata",
|
|
||||||
"unused"
|
|
||||||
],
|
|
||||||
"display": true
|
|
||||||
},
|
|
||||||
"cephpl": {
|
|
||||||
"type": "storage",
|
|
||||||
"multiplier": 1,
|
|
||||||
"base": 1024,
|
|
||||||
"compact": true,
|
|
||||||
"unit": "B",
|
|
||||||
"disks": [
|
|
||||||
"rootfs",
|
|
||||||
"mp",
|
|
||||||
"sata",
|
|
||||||
"unused"
|
|
||||||
],
|
|
||||||
"display": true
|
|
||||||
},
|
|
||||||
"network": {
|
|
||||||
"type": "network",
|
|
||||||
"multiplier": 1000000,
|
|
||||||
"base": 1000,
|
|
||||||
"compact": true,
|
|
||||||
"unit": "B/s",
|
|
||||||
"display": true
|
|
||||||
},
|
|
||||||
"pci": {
|
|
||||||
"type": "list",
|
|
||||||
"whitelist": true,
|
|
||||||
"display": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"users": {
|
|
||||||
"exampleuser@examplepool": {
|
|
||||||
"resources": {
|
|
||||||
"max": {
|
|
||||||
"cpu": ["kvm64", "host"],
|
|
||||||
"cores": 128,
|
|
||||||
"memory": 131072,
|
|
||||||
"swap": 131072,
|
|
||||||
"local": 1099511627776,
|
|
||||||
"cephpl": 1099511627776,
|
|
||||||
"network": 100000,
|
|
||||||
"pci": ["Device Name Matcher 1", "Device Name Matcher 2"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nodes": [
|
|
||||||
"examplenode1",
|
|
||||||
"examplenode2"
|
|
||||||
],
|
|
||||||
"cluster": {
|
|
||||||
"vmid": {
|
|
||||||
"min": 200,
|
|
||||||
"max": 299
|
|
||||||
},
|
|
||||||
"pool": "examplepool"
|
|
||||||
},
|
|
||||||
"templates": {
|
|
||||||
"instances": {
|
|
||||||
"lxc": {
|
|
||||||
"net0": {
|
|
||||||
"value": "name=eth0,bridge=vmbr0,ip=dhcp,ip6=dhcp,tag=10,type=veth,rate=1000",
|
|
||||||
"resource": {
|
|
||||||
"name": "network",
|
|
||||||
"amount": 1000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"qemu": {
|
|
||||||
"cpu": {
|
|
||||||
"value": "host",
|
|
||||||
"resource": null
|
|
||||||
},
|
|
||||||
"net0": {
|
|
||||||
"value": "virtio,bridge=vmbr0,tag=10,rate=1000",
|
|
||||||
"resource": {
|
|
||||||
"name": "network",
|
|
||||||
"amount": 1000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"network": {
|
|
||||||
"lxc": {
|
|
||||||
"type": "veth",
|
|
||||||
"bridge": "vmbr0",
|
|
||||||
"vlan": 10,
|
|
||||||
"ip": "dhcp",
|
|
||||||
"ip6": "dhcp"
|
|
||||||
},
|
|
||||||
"qemu": {
|
|
||||||
"type": "virtio",
|
|
||||||
"bridge": "vmbr0",
|
|
||||||
"vlan": 10
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
165
config/template.localdb.json
Normal file
165
config/template.localdb.json
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
{
|
||||||
|
"global": {
|
||||||
|
"application": {
|
||||||
|
"pveAPI": "https://pve.mydomain.example/api2/json",
|
||||||
|
"pveAPIToken": {
|
||||||
|
"user": "proxmoxaas-api",
|
||||||
|
"realm": "pve",
|
||||||
|
"id": "token",
|
||||||
|
"uuid": "token-secret-value"
|
||||||
|
},
|
||||||
|
"pveroot": {
|
||||||
|
"username": "root@pam",
|
||||||
|
"password": "rootpassword"
|
||||||
|
},
|
||||||
|
"listenPort": 80,
|
||||||
|
"hostname": "client.mydomain.example",
|
||||||
|
"domain": "mydomain.example"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"cpu": {
|
||||||
|
"type": "list",
|
||||||
|
"whitelist": true,
|
||||||
|
"display": false
|
||||||
|
},
|
||||||
|
"cores": {
|
||||||
|
"type": "numeric",
|
||||||
|
"multiplier": 1,
|
||||||
|
"base": 1024,
|
||||||
|
"compact": false,
|
||||||
|
"unit": "Cores",
|
||||||
|
"display": true
|
||||||
|
},
|
||||||
|
"memory": {
|
||||||
|
"type": "numeric",
|
||||||
|
"multiplier": 1048576,
|
||||||
|
"base": 1024,
|
||||||
|
"compact": true,
|
||||||
|
"unit": "B",
|
||||||
|
"display": true
|
||||||
|
},
|
||||||
|
"swap": {
|
||||||
|
"type": "numeric",
|
||||||
|
"multiplier": 1048576,
|
||||||
|
"base": 1024,
|
||||||
|
"compact": true,
|
||||||
|
"unit": "B",
|
||||||
|
"display": true
|
||||||
|
},
|
||||||
|
"local": {
|
||||||
|
"type": "storage",
|
||||||
|
"multiplier": 1,
|
||||||
|
"base": 1024,
|
||||||
|
"compact": true,
|
||||||
|
"unit": "B",
|
||||||
|
"disks": [
|
||||||
|
"rootfs",
|
||||||
|
"mp",
|
||||||
|
"sata",
|
||||||
|
"unused"
|
||||||
|
],
|
||||||
|
"display": true
|
||||||
|
},
|
||||||
|
"cephpl": {
|
||||||
|
"type": "storage",
|
||||||
|
"multiplier": 1,
|
||||||
|
"base": 1024,
|
||||||
|
"compact": true,
|
||||||
|
"unit": "B",
|
||||||
|
"disks": [
|
||||||
|
"rootfs",
|
||||||
|
"mp",
|
||||||
|
"sata",
|
||||||
|
"unused"
|
||||||
|
],
|
||||||
|
"display": true
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"type": "network",
|
||||||
|
"multiplier": 1000000,
|
||||||
|
"base": 1000,
|
||||||
|
"compact": true,
|
||||||
|
"unit": "B/s",
|
||||||
|
"display": true
|
||||||
|
},
|
||||||
|
"pci": {
|
||||||
|
"type": "list",
|
||||||
|
"whitelist": true,
|
||||||
|
"display": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"exampleuser@examplepool": {
|
||||||
|
"resources": {
|
||||||
|
"max": {
|
||||||
|
"cpu": [
|
||||||
|
"kvm64",
|
||||||
|
"host"
|
||||||
|
],
|
||||||
|
"cores": 128,
|
||||||
|
"memory": 131072,
|
||||||
|
"swap": 131072,
|
||||||
|
"local": 1099511627776,
|
||||||
|
"cephpl": 1099511627776,
|
||||||
|
"network": 100000,
|
||||||
|
"pci": [
|
||||||
|
"Device Name Matcher 1",
|
||||||
|
"Device Name Matcher 2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nodes": [
|
||||||
|
"examplenode1",
|
||||||
|
"examplenode2"
|
||||||
|
],
|
||||||
|
"cluster": {
|
||||||
|
"vmid": {
|
||||||
|
"min": 100,
|
||||||
|
"max": 199
|
||||||
|
},
|
||||||
|
"pool": "examplepool"
|
||||||
|
},
|
||||||
|
"templates": {
|
||||||
|
"instances": {
|
||||||
|
"lxc": {
|
||||||
|
"net0": {
|
||||||
|
"value": "name=eth0,bridge=vmbr0,ip=dhcp,ip6=dhcp,tag=10,type=veth,rate=1000",
|
||||||
|
"resource": {
|
||||||
|
"name": "network",
|
||||||
|
"amount": 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"qemu": {
|
||||||
|
"cpu": {
|
||||||
|
"value": "host",
|
||||||
|
"resource": null
|
||||||
|
},
|
||||||
|
"net0": {
|
||||||
|
"value": "virtio,bridge=vmbr0,tag=10,rate=1000",
|
||||||
|
"resource": {
|
||||||
|
"name": "network",
|
||||||
|
"amount": 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"lxc": {
|
||||||
|
"type": "veth",
|
||||||
|
"bridge": "vmbr0",
|
||||||
|
"vlan": 10,
|
||||||
|
"ip": "dhcp",
|
||||||
|
"ip6": "dhcp"
|
||||||
|
},
|
||||||
|
"qemu": {
|
||||||
|
"type": "virtio",
|
||||||
|
"bridge": "vmbr0",
|
||||||
|
"vlan": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
src/db.js
25
src/db.js
@ -22,27 +22,18 @@ class LocalDB {
|
|||||||
writeFileSync(path, JSON.stringify(this.#data));
|
writeFileSync(path, JSON.stringify(this.#data));
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplicationConfig () {
|
getGlobalConfig () {
|
||||||
return this.#data.application;
|
return this.#data.global;
|
||||||
}
|
|
||||||
|
|
||||||
getResourceConfig () {
|
|
||||||
return this.#data.resources;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserConfig (username) {
|
getUserConfig (username) {
|
||||||
if (this.#data.users[username]) {
|
return this.#data.users[username];
|
||||||
return this.#data.users[username];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const db = new LocalDB();
|
export const db = new LocalDB();
|
||||||
export const pveAPI = db.getApplicationConfig().pveAPI;
|
export const pveAPI = db.getGlobalConfig().application.pveAPI;
|
||||||
export const pveAPIToken = db.getApplicationConfig().pveAPIToken;
|
export const pveAPIToken = db.getGlobalConfig().application.pveAPIToken;
|
||||||
export const listenPort = db.getApplicationConfig().listenPort;
|
export const listenPort = db.getGlobalConfig().application.listenPort;
|
||||||
export const hostname = db.getApplicationConfig().hostname;
|
export const hostname = db.getGlobalConfig().application.hostname;
|
||||||
export const domain = db.getApplicationConfig().domain;
|
export const domain = db.getGlobalConfig().application.domain;
|
||||||
|
123
src/main.js
123
src/main.js
@ -37,18 +37,6 @@ app.get("/api/echo", (req, res) => {
|
|||||||
res.status(200).send({ body: req.body, cookies: req.cookies });
|
res.status(200).send({ body: req.body, cookies: req.cookies });
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* GET - check authentication
|
|
||||||
* responses:
|
|
||||||
* - 200: {auth: true, path: String}
|
|
||||||
* - 401: {auth: false, path: String}
|
|
||||||
*/
|
|
||||||
app.get("/api/auth", async (req, res) => {
|
|
||||||
let auth = await checkAuth(req.cookies, res);
|
|
||||||
if (!auth) { return; }
|
|
||||||
res.status(200).send({ auth: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET - proxy proxmox api without privilege elevation
|
* GET - proxy proxmox api without privilege elevation
|
||||||
* request and responses passed through to/from proxmox
|
* request and responses passed through to/from proxmox
|
||||||
@ -69,6 +57,18 @@ app.post("/api/proxmox/*", async (req, res) => { // proxy endpoint for POST prox
|
|||||||
res.status(result.status).send(result.data);
|
res.status(result.status).send(result.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET - check authentication
|
||||||
|
* responses:
|
||||||
|
* - 200: {auth: true, path: String}
|
||||||
|
* - 401: {auth: false, path: String}
|
||||||
|
*/
|
||||||
|
app.get("/api/auth", async (req, res) => {
|
||||||
|
let auth = await checkAuth(req.cookies, res);
|
||||||
|
if (!auth) { return; }
|
||||||
|
res.status(200).send({ auth: true });
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POST - safer ticket generation using proxmox authentication but adding HttpOnly
|
* POST - safer ticket generation using proxmox authentication but adding HttpOnly
|
||||||
* request:
|
* request:
|
||||||
@ -78,7 +78,7 @@ app.post("/api/proxmox/*", async (req, res) => { // proxy endpoint for POST prox
|
|||||||
* - 200: {auth: true, path: String}
|
* - 200: {auth: true, path: String}
|
||||||
* - 401: {auth: false, path: String}
|
* - 401: {auth: false, path: String}
|
||||||
*/
|
*/
|
||||||
app.post("/api/ticket", async (req, res) => {
|
app.post("/api/auth/ticket", async (req, res) => {
|
||||||
let response = await requestPVE("/access/ticket", "POST", null, JSON.stringify(req.body));
|
let response = await requestPVE("/access/ticket", "POST", null, JSON.stringify(req.body));
|
||||||
if (!(response.status === 200)) {
|
if (!(response.status === 200)) {
|
||||||
res.status(response.status).send({ auth: false });
|
res.status(response.status).send({ auth: false });
|
||||||
@ -101,7 +101,7 @@ app.post("/api/ticket", async (req, res) => {
|
|||||||
* responses:
|
* responses:
|
||||||
* - 200: {auth: false, path: String}
|
* - 200: {auth: false, path: String}
|
||||||
*/
|
*/
|
||||||
app.delete("/api/ticket", async (req, res) => {
|
app.delete("/api/auth/ticket", async (req, res) => {
|
||||||
let expire = new Date(0);
|
let expire = new Date(0);
|
||||||
res.cookie("PVEAuthCookie", "", { domain: domain, path: "/", httpOnly: true, secure: true, expires: expire });
|
res.cookie("PVEAuthCookie", "", { domain: domain, path: "/", httpOnly: true, secure: true, expires: expire });
|
||||||
res.cookie("CSRFPreventionToken", "", { domain: domain, path: "/", httpOnly: true, secure: true, expires: expire });
|
res.cookie("CSRFPreventionToken", "", { domain: domain, path: "/", httpOnly: true, secure: true, expires: expire });
|
||||||
@ -110,13 +110,35 @@ app.delete("/api/ticket", async (req, res) => {
|
|||||||
res.status(200).send({ auth: false });
|
res.status(200).send({ auth: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET - get db global resource configuration
|
||||||
|
* responses:
|
||||||
|
* - 200: Object
|
||||||
|
*/
|
||||||
|
app.get("/api/global/config/:key", async (req, res) => {
|
||||||
|
let params = {
|
||||||
|
key: req.params.key
|
||||||
|
}
|
||||||
|
// check auth
|
||||||
|
let auth = await checkAuth(req.cookies, res);
|
||||||
|
if (!auth) { return; }
|
||||||
|
let allowKeys = ["resources"];
|
||||||
|
if (allowKeys.includes(params.key)){
|
||||||
|
let config = db.getGlobalConfig();
|
||||||
|
res.status(200).send(config[params.key]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res.status(401).send({auth: false, error: `User is not authorized to access /global/config/${params.key}.`});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET - get db user resource information including allocated, free, and maximum resource values along with resource metadata
|
* GET - get db user resource information including allocated, free, and maximum resource values along with resource metadata
|
||||||
* responses:
|
* responses:
|
||||||
* - 200: {avail: Object, max: Object, used: Object, resources: Object}
|
* - 200: {avail: Object, max: Object, used: Object, resources: Object}
|
||||||
* - 401: {auth: false, path: String}
|
* - 401: {auth: false, path: String}
|
||||||
*/
|
*/
|
||||||
app.get("/api/user/resources", async (req, res) => {
|
app.get("/api/user/dynamic/resources", async (req, res) => {
|
||||||
// check auth
|
// check auth
|
||||||
let auth = await checkAuth(req.cookies, res);
|
let auth = await checkAuth(req.cookies, res);
|
||||||
if (!auth) { return; }
|
if (!auth) { return; }
|
||||||
@ -125,60 +147,31 @@ app.get("/api/user/resources", async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET - get db global resource configuration
|
* GET - get db user configuration by key
|
||||||
* responses:
|
* request:
|
||||||
* - 200: Object
|
* - key: User config key
|
||||||
*/
|
|
||||||
app.get("/api/global/config/resources", async (req, res) => {
|
|
||||||
// check auth
|
|
||||||
let auth = await checkAuth(req.cookies, res);
|
|
||||||
if (!auth) { return; }
|
|
||||||
let config = db.getResourceConfig();
|
|
||||||
res.status(200).send(config);
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GET - get db user resource configuration
|
|
||||||
* responses:
|
* responses:
|
||||||
* - 200: Object
|
* - 200: Object
|
||||||
* - 401: {auth: false, path: String}
|
* - 401: {auth: false, path: String}
|
||||||
|
* - 401: {auth: false, error: String}
|
||||||
*/
|
*/
|
||||||
app.get("/api/user/config/resources", async (req, res) => {
|
app.get(`/api/user/config/:key`, async (req, res) => {
|
||||||
|
let params = {
|
||||||
|
key: req.params.key
|
||||||
|
}
|
||||||
// check auth
|
// check auth
|
||||||
let auth = await checkAuth(req.cookies, res);
|
let auth = await checkAuth(req.cookies, res);
|
||||||
if (!auth) { return; }
|
if (!auth) { return; }
|
||||||
let config = db.getUserConfig(req.cookies.username);
|
let allowKeys = ["resources", "cluster", "nodes"];
|
||||||
res.status(200).send(config.resources);
|
if (allowKeys.includes(params.key)){
|
||||||
|
let config = db.getUserConfig(req.cookies.username);
|
||||||
|
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 db user cluster configuration
|
|
||||||
* responses:
|
|
||||||
* - 200: {pool: String, templates: {lxc: Object, qemu: Object}, vmid: {min: Number, max: Number}}
|
|
||||||
* - 401: {auth: false, path: String}
|
|
||||||
*/
|
|
||||||
app.get("/api/user/config/cluster", async (req, res) => {
|
|
||||||
// check auth
|
|
||||||
let auth = await checkAuth(req.cookies, res);
|
|
||||||
if (!auth) { return; }
|
|
||||||
let config = db.getUserConfig(req.cookies.username);
|
|
||||||
res.status(200).send(config.cluster)
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GET - get db user node configuration
|
|
||||||
* responses:
|
|
||||||
* - 200: {nodes: String[]}
|
|
||||||
* - 401: {auth: false, path: String}
|
|
||||||
*/
|
|
||||||
app.get("/api/user/config/nodes", async (req, res) => {
|
|
||||||
// check auth
|
|
||||||
let auth = await checkAuth(req.cookies, res);
|
|
||||||
if (!auth) { return; }
|
|
||||||
let config = db.getUserConfig(req.cookies.username);
|
|
||||||
res.status(200).send(config.nodes)
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POST - detach mounted disk from instance
|
* POST - detach mounted disk from instance
|
||||||
* request:
|
* request:
|
||||||
@ -259,7 +252,7 @@ app.post(`/api/:node(${nodeRegexP})/:type(${typeRegexP})/:vmid(${vmidRegexP})/di
|
|||||||
}
|
}
|
||||||
// target disk must be allowed according to source disk's storage options
|
// target disk must be allowed according to source disk's storage options
|
||||||
let diskConfig = await getDiskInfo(params.node, params.type, params.vmid, `unused${params.source}`); // get target disk
|
let diskConfig = await getDiskInfo(params.node, params.type, params.vmid, `unused${params.source}`); // get target disk
|
||||||
let resourceConfig = db.getResourceConfig();
|
let resourceConfig = db.getGlobalConfig().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();
|
||||||
@ -486,7 +479,7 @@ app.post(`/api/:node(${nodeRegexP})/:type(${typeRegexP})/:vmid(${vmidRegexP})/di
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// target disk must be allowed according to storage options
|
// target disk must be allowed according to storage options
|
||||||
let resourceConfig = db.getResourceConfig();
|
let resourceConfig = db.getGlobalConfig().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();
|
||||||
@ -811,7 +804,7 @@ app.post(`/api/:node(${nodeRegexP})/:type(${typeRegexP})/:vmid(${vmidRegexP})/pc
|
|||||||
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
|
||||||
let rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getApplicationConfig().pveroot), null);
|
let rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobalConfig().application.pveroot), null);
|
||||||
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();
|
||||||
@ -888,7 +881,7 @@ app.post(`/api/:node(${nodeRegexP})/:type(${typeRegexP})/:vmid(${vmidRegexP})/pc
|
|||||||
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
|
||||||
let rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getApplicationConfig().pveroot), null);
|
let rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobalConfig().application.pveroot), null);
|
||||||
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();
|
||||||
@ -942,7 +935,7 @@ app.delete(`/api/:node(${nodeRegexP})/:type(${typeRegexP})/:vmid(${vmidRegexP})/
|
|||||||
// setup action
|
// setup action
|
||||||
let action = JSON.stringify({ delete: `hostpci${params.hostpci}` });
|
let 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
|
||||||
let rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getApplicationConfig().pveroot), null);
|
let rootauth = await requestPVE("/access/ticket", "POST", null, JSON.stringify(db.getGlobalConfig().application.pveroot), null);
|
||||||
if (!(rootauth.status === 200)) {
|
if (!(rootauth.status === 200)) {
|
||||||
res.status(response.status).send({ auth: false, error: "API could not authenticate as root user." });
|
res.status(response.status).send({ auth: false, error: "API could not authenticate as root user." });
|
||||||
res.end();
|
res.end();
|
||||||
|
@ -28,7 +28,7 @@ export async function checkAuth (cookies, res, vmpath = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getUserResources (req, username) {
|
export async function getUserResources (req, username) {
|
||||||
const dbResources = db.getResourceConfig();
|
const dbResources = db.getGlobalConfig().resources;
|
||||||
const used = await getUsedResources(req, dbResources);
|
const used = await getUsedResources(req, dbResources);
|
||||||
const max = db.getUserConfig(username).resources.max;
|
const max = db.getUserConfig(username).resources.max;
|
||||||
const avail = {};
|
const avail = {};
|
||||||
|
Loading…
Reference in New Issue
Block a user