n8n-nodes-proxmox
Version:
n8n community node for Proxmox Virtual Environment (VE) API integration with VM, container, storage, and cluster management capabilities
160 lines (159 loc) • 6.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleProxMoxError = handleProxMoxError;
exports.validateParameters = validateParameters;
exports.validateNodeName = validateNodeName;
exports.validateVmId = validateVmId;
exports.validateStorageName = validateStorageName;
exports.parseResourceId = parseResourceId;
const n8n_workflow_1 = require("n8n-workflow");
/**
* Handle ProxMox API errors with context-specific messages
*/
function handleProxMoxError(error, operation, resource) {
let message = `Failed to ${operation} ${resource}`;
if (error instanceof n8n_workflow_1.NodeApiError || error instanceof n8n_workflow_1.NodeOperationError) {
throw error;
}
// Handle specific ProxMox error cases
if (error.response) {
const statusCode = error.statusCode || error.response.status;
const errorBody = error.error || error.response.body || error.response.data;
switch (statusCode) {
case 400:
message = `Bad request: Invalid parameters for ${operation} ${resource}`;
if (errorBody === null || errorBody === void 0 ? void 0 : errorBody.errors) {
const errors = Array.isArray(errorBody.errors)
? errorBody.errors.join(', ')
: JSON.stringify(errorBody.errors);
message += ` - ${errors}`;
}
break;
case 401:
message = 'Authentication failed. Please check your ProxMox credentials.';
break;
case 403:
message = `Permission denied. User lacks privileges to ${operation} ${resource}.`;
break;
case 404:
message = `${resource} not found. Please check the resource ID or name.`;
break;
case 409:
message = `Conflict: ${resource} already exists or is in an incompatible state.`;
break;
case 422:
message = `Validation error for ${operation} ${resource}`;
if (errorBody === null || errorBody === void 0 ? void 0 : errorBody.errors) {
const errors = Array.isArray(errorBody.errors)
? errorBody.errors.join(', ')
: JSON.stringify(errorBody.errors);
message += ` - ${errors}`;
}
break;
case 500:
message = `ProxMox server error during ${operation} ${resource}. Please try again later.`;
break;
case 503:
message = `ProxMox service unavailable. The node may be busy or under maintenance.`;
break;
default:
if (errorBody) {
if (typeof errorBody === 'object') {
if (errorBody.message) {
message = errorBody.message;
}
else if (errorBody.reason) {
message = errorBody.reason;
}
else if (errorBody.errors) {
const errors = Array.isArray(errorBody.errors)
? errorBody.errors.join(', ')
: JSON.stringify(errorBody.errors);
message = `Error ${operation} ${resource}: ${errors}`;
}
}
else if (typeof errorBody === 'string') {
message = errorBody;
}
}
}
}
else if (error.message) {
message = error.message;
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), message);
}
/**
* Validate required parameters for ProxMox operations
*/
function validateParameters(parameters, required, operation) {
const missing = required.filter((param) => !parameters[param]);
if (missing.length > 0) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Missing required parameters for ${operation}: ${missing.join(', ')}`);
}
}
/**
* Validate ProxMox node name format
*/
function validateNodeName(nodeName) {
// ProxMox node names should be valid hostnames
const nodeNameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/;
return nodeNameRegex.test(nodeName) && nodeName.length <= 63;
}
/**
* Validate ProxMox VM/Container ID format
*/
function validateVmId(vmId) {
const id = typeof vmId === 'string' ? parseInt(vmId, 10) : vmId;
return !isNaN(id) && id >= 100 && id <= 999999999;
}
/**
* Validate ProxMox storage name format
*/
function validateStorageName(storageName) {
// Storage names in ProxMox follow specific naming conventions
const storageNameRegex = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
return storageNameRegex.test(storageName) && storageName.length <= 64;
}
/**
* Parse and validate ProxMox resource ID from various formats
*/
function parseResourceId(resourceId) {
// Handle different ProxMox resource ID formats:
// - node/pve (node reference)
// - node/qemu/vmid (VM reference)
// - node/lxc/vmid (Container reference)
// - node/storage/storagename (Storage reference)
const parts = resourceId.split('/');
const result = {
node: parts[0],
};
if (parts.length >= 2) {
result.type = parts[1];
if (parts.length >= 3) {
if (parts[1] === 'qemu' || parts[1] === 'lxc') {
const vmid = parseInt(parts[2], 10);
if (isNaN(vmid)) {
throw new Error(`Invalid VM/Container ID: ${parts[2]}`);
}
result.vmid = vmid;
}
else if (parts[1] === 'storage') {
result.storage = parts[2];
}
}
}
// Validate node name
if (!validateNodeName(result.node)) {
throw new Error(`Invalid node name: ${result.node}`);
}
// Validate VM ID if present
if (result.vmid !== undefined && !validateVmId(result.vmid)) {
throw new Error(`Invalid VM/Container ID: ${result.vmid}`);
}
// Validate storage name if present
if (result.storage !== undefined && !validateStorageName(result.storage)) {
throw new Error(`Invalid storage name: ${result.storage}`);
}
return result;
}