diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 6faba3213..9202c249c 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -433,5 +433,11 @@ "cloudflared": { "origin_ip": "Origin IP", "status": "Status" + }, + "proxmoxbackupserver": { + "datastore_usage": "Datastore", + "failed_tasks_24h": "Failed Tasks 24h", + "cpu_usage": "CPU", + "memory_usage": "Memory" } } \ No newline at end of file diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js index 7dc9f9e6a..23e065246 100644 --- a/src/utils/proxy/handlers/credentialed.js +++ b/src/utils/proxy/handlers/credentialed.js @@ -34,6 +34,9 @@ export default async function credentialedProxyHandler(req, res, map) { headers.Authorization = `Bearer ${widget.key}`; } else if (widget.type === "proxmox") { headers.Authorization = `PVEAPIToken=${widget.username}=${widget.password}`; + } else if (widget.type === "proxmoxbackupserver") { + delete headers["Content-Type"]; + headers.Authorization = `PBSAPIToken=${widget.username}:${widget.password}`; } else if (widget.type === "autobrr") { headers["X-API-Token"] = `${widget.key}`; } else if (widget.type === "tubearchivist") { diff --git a/src/widgets/components.js b/src/widgets/components.js index 2896f159f..17a2d7e34 100644 --- a/src/widgets/components.js +++ b/src/widgets/components.js @@ -37,6 +37,7 @@ const components = { opnsense: dynamic(() => import("./opnsense/component")), overseerr: dynamic(() => import("./overseerr/component")), paperlessngx: dynamic(() => import("./paperlessngx/component")), + proxmoxbackupserver: dynamic(() => import("./proxmoxbackupserver/component")), pihole: dynamic(() => import("./pihole/component")), plex: dynamic(() => import("./plex/component")), portainer: dynamic(() => import("./portainer/component")), diff --git a/src/widgets/proxmoxbackupserver/component.jsx b/src/widgets/proxmoxbackupserver/component.jsx new file mode 100644 index 000000000..96151e256 --- /dev/null +++ b/src/widgets/proxmoxbackupserver/component.jsx @@ -0,0 +1,45 @@ +import { useTranslation } from "next-i18next"; + +import Container from "components/services/widget/container"; +import Block from "components/services/widget/block"; +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { t } = useTranslation(); + + const { widget } = service; + + const { data: datastoreData, error: datastoreError } = useWidgetAPI(widget, "status/datastore-usage"); + const { data: tasksData, error: tasksError } = useWidgetAPI(widget, "nodes/localhost/tasks"); + const { data: hostData, error: hostError } = useWidgetAPI(widget, "nodes/localhost/status"); + + if (datastoreError || tasksError || hostError) { + const finalError = tasksError ?? datastoreError ?? hostError; + return ; + } + + if (!datastoreData || !tasksData || !hostData) { + return ( + + + + + + + ); + } + + const datastoreUsage = datastoreData.data[0].used / datastoreData.data[0].total * 100; + const cpuUsage = hostData.data.cpu * 100; + const memoryUsage = hostData.data.memory.used / hostData.data.memory.total * 100; + const failedTasks = tasksData.total >= 100 ? "99+" : tasksData.total; + + return ( + + + + + + + ); +} diff --git a/src/widgets/proxmoxbackupserver/widget.js b/src/widgets/proxmoxbackupserver/widget.js new file mode 100644 index 000000000..0f2623304 --- /dev/null +++ b/src/widgets/proxmoxbackupserver/widget.js @@ -0,0 +1,22 @@ +import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; + +const since = Date.now() - (24 * 60 * 60 * 1000); + +const widget = { + api: "{url}/api2/json/{endpoint}", + proxyHandler: credentialedProxyHandler, + + mappings: { + "status/datastore-usage": { + endpoint: "status/datastore-usage", + }, + "nodes/localhost/tasks": { + endpoint: `nodes/localhost/tasks?errors=true&limit=100&since=${since}`, + }, + "nodes/localhost/status": { + endpoint: "nodes/localhost/status", + }, + }, +}; + +export default widget; diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js index a1cc061c1..42f7aa7b6 100644 --- a/src/widgets/widgets.js +++ b/src/widgets/widgets.js @@ -31,6 +31,7 @@ import ombi from "./ombi/widget"; import opnsense from "./opnsense/widget"; import overseerr from "./overseerr/widget"; import paperlessngx from "./paperlessngx/widget"; +import proxmoxbackupserver from "./proxmoxbackupserver/widget"; import pihole from "./pihole/widget"; import plex from "./plex/widget"; import portainer from "./portainer/widget"; @@ -92,6 +93,7 @@ const widgets = { opnsense, overseerr, paperlessngx, + proxmoxbackupserver, pihole, plex, portainer,