UNPKG

n8n-nodes-proxmox

Version:

n8n community node for Proxmox Virtual Environment (VE) API integration with VM, container, storage, and cluster management capabilities

252 lines (221 loc) 6.84 kB
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, NodeOperationError, } from 'n8n-workflow'; import { clusterOperations, clusterFields } from './descriptions/cluster.descriptions'; import { vmOperations, vmFields } from './descriptions/vm.descriptions'; import { containerOperations, containerFields } from './descriptions/container.descriptions'; import { storageOperations, storageFields } from './descriptions/storage.descriptions'; import { backupOperations, backupFields } from './descriptions/backup.descriptions'; import { executeClusterOperation } from './methods/cluster.methods'; import { executeVmOperation } from './methods/vm.methods'; import { executeContainerOperation } from './methods/container.methods'; import { executeStorageOperation } from './methods/storage.methods'; import { executeBackupOperation } from './methods/backup.methods'; import { logger } from './helpers/logger'; export class ProxMox implements INodeType { description: INodeTypeDescription = { displayName: 'ProxMox VE', name: 'proxMox', icon: 'file:ProxMox.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Interact with ProxMox Virtual Environment API for managing VMs, containers, storage, and cluster operations', defaults: { name: 'ProxMox VE', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'proxMoxApi', required: true, }, ], requestDefaults: { baseURL: '={{$credentials.host}}:{{$credentials.port}}/api2/json', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, }, usableAsTool: true, properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Cluster', value: 'cluster', description: 'Manage cluster operations', }, { name: 'Virtual Machine', value: 'vm', description: 'Manage virtual machines (QEMU/KVM)', }, { name: 'Container', value: 'container', description: 'Manage LXC containers', }, { name: 'Storage', value: 'storage', description: 'Manage storage and file operations', }, { name: 'Backup', value: 'backup', description: 'Manage backups and restore operations', }, ], default: 'vm', required: true, }, // Cluster operations clusterOperations, ...clusterFields, // VM operations vmOperations, ...vmFields, // Container operations containerOperations, ...containerFields, // Storage operations storageOperations, ...storageFields, // Backup operations backupOperations, ...backupFields, // Continue on Fail { displayName: 'Continue on Fail', name: 'continueOnFail', type: 'boolean', default: false, description: 'Whether to continue the workflow if this node fails', }, ], }; async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> { console.log('\n\n========== PROXMOX NODE EXECUTION STARTED =========='); try { const items = this.getInputData(); console.log('Input data retrieved:', { itemCount: items.length }); const returnData: INodeExecutionData[] = []; const length = items.length; console.log('Attempting to get resource parameter...'); const resource = this.getNodeParameter('resource', 0) as string; console.log('Resource parameter retrieved:', resource); console.log('Attempting to get operation parameter...'); const operation = this.getNodeParameter('operation', 0) as string; console.log('Operation parameter retrieved:', operation); logger.info('node', `ProxMox node execution started`, { resource, operation, itemCount: length, }); for (let i = 0; i < length; i++) { console.log(`Processing item ${i + 1}/${length}`); try { let responseData; console.log(`Executing ${resource} - ${operation} operation`); switch (resource) { case 'cluster': console.log('Calling executeClusterOperation...'); responseData = await executeClusterOperation.call(this, operation, i); break; case 'vm': console.log('Calling executeVmOperation...'); responseData = await executeVmOperation.call(this, operation, i); break; case 'container': console.log('Calling executeContainerOperation...'); responseData = await executeContainerOperation.call(this, operation, i); break; case 'storage': console.log('Calling executeStorageOperation...'); responseData = await executeStorageOperation.call(this, operation, i); break; case 'backup': console.log('Calling executeBackupOperation...'); responseData = await executeBackupOperation.call(this, operation, i); break; default: throw new NodeOperationError( this.getNode(), `The resource "${resource}" is not known!`, { itemIndex: i }, ); } console.log('Operation completed successfully, processing response...'); // Handle array responses if (Array.isArray(responseData)) { responseData.forEach((item) => { returnData.push({ json: item, pairedItem: { item: i }, }); }); } else { returnData.push({ json: responseData, pairedItem: { item: i }, }); } } catch (error) { console.log('=== ERROR CAUGHT IN ITEM PROCESSING ==='); console.log('Error object:', error); console.log('Error message:', error.message); console.log('Error stack:', error.stack); console.log('Error type:', typeof error); console.log('Error constructor:', error.constructor.name); logger.error('node', `ProxMox node execution failed`, { resource, operation, itemIndex: i, error: error.message, }); if (this.continueOnFail()) { returnData.push({ json: { error: error.message, itemIndex: i, resource, operation, }, pairedItem: { item: i }, }); continue; } throw error; } } logger.info('node', `ProxMox node execution completed`, { resource, operation, itemCount: length, resultCount: returnData.length, }); console.log('========== PROXMOX NODE EXECUTION COMPLETED ==========\n\n'); return [returnData]; } catch (globalError) { console.log('ERROR in node execution:'); console.log(globalError); if (this.continueOnFail()) { console.log('Continue on fail is enabled, returning error as output'); return [[{ json: { error: globalError.message } }]]; } throw globalError; } } }