From aa8148fc16b87b5856be4d32785987c25cc8de46 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Tue, 11 Jul 2023 18:48:45 +0000 Subject: [PATCH] add /cluster/statushash endpoint --- src/main.js | 25 +++++++++++++++++++++---- src/utils.js | 9 +++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/main.js b/src/main.js index c2c6965..c5df359 100644 --- a/src/main.js +++ b/src/main.js @@ -6,7 +6,7 @@ import morgan from "morgan"; import { api } from "./package.js"; import { requestPVE, handleResponse, getDiskInfo, getDeviceInfo, getNodeAvailDevices } from "./pve.js"; -import { checkAuth, approveResources, getUserResources } from "./utils.js"; +import { checkAuth, approveResources, getUserResources, getObjectHash } from "./utils.js"; import { db, pveAPIToken, listenPort, hostname, domain } from "./db.js"; const app = express(); @@ -1198,11 +1198,28 @@ app.delete(`/api/:node(${nodeRegexP})/:type(${typeRegexP})/:vmid(${vmidRegexP})/ /** * GET - get hash of current cluster resources states + * Client can use this endpoint to check for cluster state changes to avoid costly data transfers to the client. * responses: - * - string + * - 401: {auth: false} + * - 200: string */ -app.get(`/cluster/statushash`, async (req, res) => { - +app.get(`/api/cluster/statushash`, async (req, res) => { + // check auth + const auth = await checkAuth(req.cookies, res); + if (!auth) { + return; + } + // get current cluster resources + let status = (await requestPVE("/cluster/resources", "GET", req.cookies)).data.data; + // filter out just state information of resources that are needed + let resources = ["lxc", "qemu", "node"]; + let state = {}; + status.forEach((element) => { + if (resources.includes(element.type)) { + state[element.id] = element.status; + } + }); + res.status(200).send(getObjectHash(state)); }); app.listen(listenPort, () => { diff --git a/src/utils.js b/src/utils.js index c9861b4..0185849 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,3 +1,5 @@ +import {createHash} from "crypto"; + import { getUsedResources, requestPVE } from "./pve.js"; import { db } from "./db.js"; @@ -91,3 +93,10 @@ export async function approveResources (req, username, request) { }); return approved; // if all requested resources pass, allow } + + +export function getObjectHash (object, alg = "sha256", format = "hex") { + const hash = createHash(alg); + hash.update(JSON.stringify(object, Object.keys(object).sort())); + return hash.digest(format); +} \ No newline at end of file