n8n-nodes-proxmox
Version:
n8n community node for Proxmox Virtual Environment (VE) API integration with VM, container, storage, and cluster management capabilities
164 lines (163 loc) • 7.38 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeStorageOperation = executeStorageOperation;
const apiRequest_1 = require("../helpers/apiRequest");
const errorHandler_1 = require("../helpers/errorHandler");
const logger_1 = require("../helpers/logger");
async function executeStorageOperation(operation, i) {
try {
logger_1.logger.operation('storage', operation, 'start', { operation });
let response;
switch (operation) {
case 'getAll':
response = await getAllStorage.call(this, i);
break;
case 'get':
response = await getStorage.call(this, i);
break;
case 'getContent':
response = await getStorageContent.call(this, i);
break;
case 'getStatus':
response = await getStorageStatus.call(this, i);
break;
case 'upload':
response = await uploadToStorage.call(this, i);
break;
case 'deleteFile':
response = await deleteFileFromStorage.call(this, i);
break;
default:
throw new Error(`Unknown storage operation: ${operation}`);
}
logger_1.logger.operation('storage', operation, 'success', { operation });
return response;
}
catch (error) {
logger_1.logger.operation('storage', operation, 'error', { operation, error: error.message });
return errorHandler_1.handleProxMoxError.call(this, error, operation, 'storage');
}
}
async function getAllStorage(i) {
const returnAll = this.getNodeParameter('returnAll', i);
const additionalFields = this.getNodeParameter('additionalFields', i, {});
let qs = {};
// Add filters
if (additionalFields.enabled !== undefined) {
qs.enabled = additionalFields.enabled ? 1 : 0;
}
logger_1.logger.debug('storage', 'Getting all storage configurations', { additionalFields });
if (returnAll) {
return await apiRequest_1.apiRequestAllItems.call(this, 'GET', '/storage', {}, qs);
}
else {
const limit = this.getNodeParameter('limit', i);
// ProxMox API doesn't support limit parameter, we'll slice the results client-side
const response = await apiRequest_1.apiRequest.call(this, 'GET', '/storage', {}, qs);
return Array.isArray(response) ? response.slice(0, limit) : [response];
}
}
async function getStorage(i) {
const storageId = this.getNodeParameter('storageId', i);
errorHandler_1.validateParameters.call(this, { storageId }, ['storageId'], 'get storage');
logger_1.logger.debug('storage', 'Getting storage configuration', { storageId });
return await apiRequest_1.apiRequest.call(this, 'GET', `/storage/${storageId}`);
}
async function getStorageContent(i) {
const nodeName = this.getNodeParameter('nodeName', i);
const storageId = this.getNodeParameter('storageId', i);
const returnAll = this.getNodeParameter('returnAll', i);
const contentType = this.getNodeParameter('contentType', i, '');
const additionalFields = this.getNodeParameter('additionalFields', i, {});
errorHandler_1.validateParameters.call(this, { nodeName, storageId }, ['nodeName', 'storageId'], 'get storage content');
let qs = {};
if (contentType) {
qs.content = contentType;
}
// Add additional filters
if (additionalFields.vmid) {
qs.vmid = additionalFields.vmid;
}
if (additionalFields.format) {
qs.format = additionalFields.format;
}
logger_1.logger.debug('storage', 'Getting storage content', {
nodeName,
storageId,
contentType,
additionalFields,
});
if (returnAll) {
return await apiRequest_1.apiRequestAllItems.call(this, 'GET', `/nodes/${nodeName}/storage/${storageId}/content`, {}, qs);
}
else {
const limit = this.getNodeParameter('limit', i);
// ProxMox API doesn't support limit parameter, we'll slice the results client-side
const response = await apiRequest_1.apiRequest.call(this, 'GET', `/nodes/${nodeName}/storage/${storageId}/content`, {}, qs);
return Array.isArray(response) ? response.slice(0, limit) : [response];
}
}
async function getStorageStatus(i) {
const nodeName = this.getNodeParameter('nodeName', i);
const storageId = this.getNodeParameter('storageId', i);
errorHandler_1.validateParameters.call(this, { nodeName, storageId }, ['nodeName', 'storageId'], 'get storage status');
logger_1.logger.debug('storage', 'Getting storage status', { nodeName, storageId });
return await apiRequest_1.apiRequest.call(this, 'GET', `/nodes/${nodeName}/storage/${storageId}/status`);
}
async function uploadToStorage(i) {
const nodeName = this.getNodeParameter('nodeName', i);
const storageId = this.getNodeParameter('storageId', i);
const fileName = this.getNodeParameter('fileName', i);
const fileContent = this.getNodeParameter('fileContent', i);
const uploadOptions = this.getNodeParameter('uploadOptions', i, {});
errorHandler_1.validateParameters.call(this, { nodeName, storageId, fileName, fileContent }, ['nodeName', 'storageId', 'fileName', 'fileContent'], 'upload to storage');
// Decode base64 content
let decodedContent;
try {
decodedContent = Buffer.from(fileContent, 'base64');
}
catch (error) {
throw new Error(`Invalid base64 file content: ${error.message}`);
}
const body = {
filename: fileName,
content: uploadOptions.content || 'iso',
...uploadOptions,
};
// Handle checksum validation if provided
if (uploadOptions.checksum) {
const [algorithm, hash] = uploadOptions.checksum.split(':');
if (algorithm && hash) {
body.checksum = hash;
body['checksum-algorithm'] = algorithm;
}
}
logger_1.logger.debug('storage', 'Uploading file to storage', {
nodeName,
storageId,
fileName,
size: decodedContent.length,
});
// Note: This is a simplified implementation. In a real scenario, you would need to handle
// multipart form data upload with the actual file content. The ProxMox API expects
// a multipart/form-data request with the file as a binary attachment.
return await apiRequest_1.apiRequest.call(this, 'POST', `/nodes/${nodeName}/storage/${storageId}/upload`, {
...body,
content: decodedContent.toString('base64'),
});
}
async function deleteFileFromStorage(i) {
const nodeName = this.getNodeParameter('nodeName', i);
const storageId = this.getNodeParameter('storageId', i);
const filePath = this.getNodeParameter('filePath', i);
errorHandler_1.validateParameters.call(this, { nodeName, storageId, filePath }, ['nodeName', 'storageId', 'filePath'], 'delete file from storage');
// The volume ID format is typically storage:path
const volumeId = `${storageId}:${filePath}`;
logger_1.logger.debug('storage', 'Deleting file from storage', {
nodeName,
storageId,
filePath,
volumeId,
});
return await apiRequest_1.apiRequest.call(this, 'DELETE', `/nodes/${nodeName}/storage/${storageId}/content/${encodeURIComponent(volumeId)}`);
}