Fix: Resolve PBS API /tasks issue and update README

This commit is contained in:
courtmanr@gmail.com
2025-04-28 12:34:17 +01:00
parent aab584ca79
commit 25b51160da
2 changed files with 37 additions and 6 deletions
+8 -5
View File
@@ -154,17 +154,20 @@ If you are configuring PBS monitoring, you need a separate API token created wit
4. **Assign permissions**
* Under `Configuration` → `Access Control`, select `Permissions`.
* Click `Add` → `API Token Permission`.
* Path: `/datastore` (This grants access to view datastores and their contents, including backup snapshots).
* API Token: Select the token you created (e.g., "pulse-monitor@pam!pulse").
* Role: `DatastoreAudit` (Provides read-only access to datastore contents and backups).
* **Path:** `/` (Grant permissions at the root level for broad access needed by Pulse).
* **API Token:** Select the token you created (e.g., "pulse-monitor@pam!pulse").
* **Role:** `Audit` (This role provides necessary read-only access, including system status and task history).
* Ensure `Propagate` is checked.
* Click `Add`.
* *(Note: While `DatastoreAudit` on `/datastore` is usually sufficient for backup status, if you still encounter issues fetching task lists, you might need broader permissions like `Audit` on path `/` for the token, although this has shown inconsistent behaviour with API tokens vs user sessions in some PBS versions).*
*
* **Note on Permissions & API Behavior:** While minimal roles like `DatastoreAudit` might seem sufficient, testing (on PBS v3.3.4) revealed specific API behavior with tokens. GET requests to `/tasks` failed with a `400 Bad Request ("value does not match the regex pattern")` if the request included a `Content-Type` header (which some HTTP clients add by default), whereas requests omitting this header succeeded. Pulse now includes a workaround for this client-side. However, using the broader `Audit` role on the root path `/` also ensures Pulse can reliably access all necessary data (datastores, snapshots, task history) for full monitoring functionality. This role is still read-only.
5. **Update your `server/.env` file** with the PBS `Token ID` (`PBS_TOKEN_ID`) and the `Secret` (`PBS_TOKEN_SECRET`).
### Required Permissions
The `PVEAuditor` role is recommended as it provides the necessary read-only permissions for Pulse to monitor your Proxmox environment:
**Proxmox VE:**
The `PVEAuditor` role is recommended as it provides the necessary read-only permissions for Pulse to monitor your Proxmox VE environment:
- `Datastore.Audit`
- `Permissions.Read` (implicitly included)
- `Pool.Audit`
+29 -1
View File
@@ -280,12 +280,37 @@ async function initializeAllPbsClients() {
httpsAgent: new https.Agent({
rejectUnauthorized: !config.allowSelfSignedCerts
}),
headers: { 'Content-Type': 'application/json' }
// REMOVED default headers here
// headers: { 'Content-Type': 'application/json' }
});
pbsAxiosInstance.interceptors.request.use(reqConfig => {
// Correct PBS format: PBSAPIToken=TOKENID:TOKENSECRET
reqConfig.headers.Authorization = `PBSAPIToken=${config.tokenId}:${config.tokenSecret}`;
// ---> WORKAROUND for PBS API Bug <---
// PBS API (tested on 3.3.4) incorrectly returns 400 Bad Request ("value does not match regex pattern")
// on GET requests (e.g., /tasks) if a 'Content-Type' header is present when using API Token authentication.
// Therefore, explicitly remove 'Content-Type' for GET requests.
// It seems fine/required for POST/PUT requests, so add it back for non-GET.
// See Bugzilla #6365 for related details.
if (reqConfig.method && reqConfig.method.toLowerCase() !== 'get') {
reqConfig.headers['Content-Type'] = 'application/json';
} else {
// Ensure Content-Type is removed for GET requests
delete reqConfig.headers['Content-Type'];
}
// ---> END WORKAROUND <---
// ---> ADD: Set default Accept header (optional but good practice)
if (!reqConfig.headers['Accept']) {
reqConfig.headers['Accept'] = 'application/json, text/plain, */*';
}
// ---> END ADD
// ---> DEBUG: Log outgoing request headers (can be removed later)
// console.log(`DEBUG: Axios Request Headers for ${config.name}:`, JSON.stringify(reqConfig.headers)); // REMOVED
// ---> END DEBUG
return reqConfig;
});
@@ -1233,6 +1258,9 @@ async function fetchAllPbsTasksForProcessing(pbsClient, nodeName) {
errors: 1, // RESTORED
};
const paramsToSend = Object.keys(requestParams).length > 0 ? { params: requestParams } : {};
// ---> DEBUG: Log outgoing request URL and params
// console.log(`DEBUG: Axios GET Request to ${pbsClient.config.name} - URL: ${requestUrl}, ParamsObj: ${JSON.stringify(paramsToSend)}`); // REMOVED
// ---> END DEBUG
const response = await pbsClient.client.get(requestUrl, paramsToSend);
const allTasks = response.data?.data ?? [];
return { tasks: allTasks, error: false };