UNPKG

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
"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)}`); }