UNPKG

n8n-nodes-netbox

Version:

n8n community node for NetBox API integration with comprehensive DCIM, IPAM, Virtualization, Circuits, Wireless, and data center management operations

297 lines (296 loc) 11.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.listDevices = listDevices; exports.getDevice = getDevice; exports.createDevice = createDevice; exports.updateDevice = updateDevice; exports.deleteDevice = deleteDevice; exports.getInterfaces = getInterfaces; exports.getConsolePorts = getConsolePorts; exports.getConfigContext = getConfigContext; exports.assignTag = assignTag; const apiRequest_1 = require("../../../helpers/apiRequest"); const responseFormatter_1 = require("../../../helpers/responseFormatter"); async function listDevices() { try { // Get pagination parameters const returnAll = this.getNodeParameter('returnAll', 0); // Get filters - this will include all the advanced filter fields const filters = this.getNodeParameter('filters', 0, {}); // Prepare query parameters const queryParams = { ...filters }; let responseData; if (returnAll) { // Add higher limit to the first query when listing devices if (!queryParams.limit) { queryParams.limit = 500; // Higher limit for faster pagination } responseData = await apiRequest_1.apiRequestAllItems.call(this, 'GET', '/api/dcim/devices/', {}, queryParams); return responseFormatter_1.formatResponse.call(this, responseData); } else { const limit = this.getNodeParameter('limit', 0); queryParams.limit = limit; responseData = await apiRequest_1.apiRequest.call(this, 'GET', '/api/dcim/devices/', {}, queryParams); return responseFormatter_1.formatResponse.call(this, responseData); } } catch (error) { console.log('ERROR in listDevices:', error); throw error; } } async function getDevice() { try { const deviceId = this.getNodeParameter('deviceId', 0); const endpoint = `/api/dcim/devices/${deviceId}/`; const response = await apiRequest_1.apiRequest.call(this, 'GET', endpoint, {}, {}); return responseFormatter_1.formatResponse.call(this, response); } catch (error) { console.log('ERROR in getDevice:', error); throw error; } } async function createDevice() { try { // Get required fields const name = this.getNodeParameter('name', 0); const deviceTypeId = this.getNodeParameter('device_type_id', 0); const siteId = this.getNodeParameter('site_id', 0); // Get additional fields const additionalFields = this.getNodeParameter('additionalFields', 0, {}); // Build the device data const deviceData = { name, device_type: deviceTypeId, site: siteId, ...additionalFields, }; // Handle tags (convert from comma-separated to array) if (additionalFields.tags && typeof additionalFields.tags === 'string') { const tagsArray = additionalFields.tags .split(',') .map((tag) => tag.trim()) .filter((tag) => tag !== ''); deviceData.tags = tagsArray; delete additionalFields.tags; } // Handle custom fields (parse JSON string to object) if (additionalFields.custom_fields && typeof additionalFields.custom_fields === 'string') { try { deviceData.custom_fields = JSON.parse(additionalFields.custom_fields); } catch (e) { throw new Error(`Invalid JSON in custom_fields: ${e.message}`); } delete additionalFields.custom_fields; } const endpoint = '/api/dcim/devices/'; const response = await apiRequest_1.apiRequest.call(this, 'POST', endpoint, deviceData, {}); return responseFormatter_1.formatResponse.call(this, response); } catch (error) { console.log('ERROR in createDevice:', error); throw error; } } async function updateDevice() { try { const deviceId = this.getNodeParameter('deviceId', 0); const updateFields = this.getNodeParameter('updateFields', 0, {}); // Handle tags (convert from comma-separated to array) if (updateFields.tags && typeof updateFields.tags === 'string') { const tagsArray = updateFields.tags .split(',') .map((tag) => tag.trim()) .filter((tag) => tag !== ''); updateFields.tags = tagsArray; } // Handle custom fields (parse JSON string to object) if (updateFields.custom_fields && typeof updateFields.custom_fields === 'string') { try { updateFields.custom_fields = JSON.parse(updateFields.custom_fields); } catch (e) { throw new Error(`Invalid JSON in custom_fields: ${e.message}`); } } const endpoint = `/api/dcim/devices/${deviceId}/`; const response = await apiRequest_1.apiRequest.call(this, 'PATCH', endpoint, updateFields, {}); return responseFormatter_1.formatResponse.call(this, response); } catch (error) { console.log('ERROR in updateDevice:', error); throw error; } } async function deleteDevice() { try { const deviceId = this.getNodeParameter('deviceId', 0); const endpoint = `/api/dcim/devices/${deviceId}/`; await apiRequest_1.apiRequest.call(this, 'DELETE', endpoint, {}, {}); return [{ json: { success: true } }]; } catch (error) { console.log('ERROR in deleteDevice:', error); throw error; } } async function getInterfaces() { try { const deviceId = this.getNodeParameter('deviceId', 0); const returnAll = this.getNodeParameter('returnAll', 0, false); const endpoint = `/api/dcim/interfaces/`; const queryParams = { device_id: deviceId }; let responseData; if (returnAll === true) { responseData = await apiRequest_1.apiRequestAllItems.call(this, 'GET', endpoint, {}, queryParams); } else { const limit = this.getNodeParameter('limit', 0, 50); queryParams.limit = limit; responseData = await apiRequest_1.apiRequest.call(this, 'GET', endpoint, {}, queryParams); } return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { console.log('ERROR in getInterfaces:', error); throw error; } } async function getConsolePorts() { try { const deviceId = this.getNodeParameter('deviceId', 0); const returnAll = this.getNodeParameter('returnAll', 0, false); const endpoint = `/api/dcim/console-ports/`; const queryParams = { device_id: deviceId }; let responseData; if (returnAll === true) { responseData = await apiRequest_1.apiRequestAllItems.call(this, 'GET', endpoint, {}, queryParams); } else { const limit = this.getNodeParameter('limit', 0, 50); queryParams.limit = limit; responseData = await apiRequest_1.apiRequest.call(this, 'GET', endpoint, {}, queryParams); } return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { console.log('ERROR in getConsolePorts:', error); throw error; } } async function getConfigContext() { try { const deviceId = this.getNodeParameter('deviceId', 0); const endpoint = `/api/dcim/devices/${deviceId}/config-context/`; const responseData = await apiRequest_1.apiRequest.call(this, 'GET', endpoint, {}, {}); return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { console.log('ERROR in getConfigContext:', error); throw error; } } async function assignTag() { try { const deviceId = this.getNodeParameter('deviceId', 0); const tagIdentifier = this.getNodeParameter('tagId', 0); const action = this.getNodeParameter('action', 0); // First, get the current device to retrieve its existing tags const deviceEndpoint = `/api/dcim/devices/${deviceId}/`; const deviceResponse = await apiRequest_1.apiRequest.call(this, 'GET', deviceEndpoint, {}, {}); // Next, find the tag by ID or name let tagId; let tag; // Check if the tag identifier is numeric (ID) or string (name) if (!isNaN(Number(tagIdentifier))) { // It's an ID tagId = Number(tagIdentifier); const tagEndpoint = `/api/extras/tags/${tagId}/`; tag = await apiRequest_1.apiRequest.call(this, 'GET', tagEndpoint, {}, {}); } else { // It's a name, search for it const tagsEndpoint = '/api/extras/tags/'; const tagsResponse = await apiRequest_1.apiRequest.call(this, 'GET', tagsEndpoint, {}, { name: tagIdentifier }); if (!tagsResponse.results || tagsResponse.results.length === 0) { throw new Error(`Tag with name "${tagIdentifier}" not found`); } tag = tagsResponse.results[0]; tagId = tag.id; } // Get the current tags from the device const existingTags = deviceResponse.tags || []; const existingTagIds = existingTags.map((t) => t.id); // Determine the new tags array based on the action let updatedTagIds; if (action === 'add') { // Only add if not already present if (!existingTagIds.includes(tagId)) { updatedTagIds = [...existingTagIds, tagId]; } else { // Tag already assigned, no change needed return [ { json: { success: true, message: `Tag "${tag.name}" is already assigned to device` } }, ]; } } else { // action === 'remove' if (existingTagIds.includes(tagId)) { // Fix: Add explicit type for id parameter updatedTagIds = existingTagIds.filter((id) => id !== tagId); } else { // Tag wasn't assigned, no change needed return [ { json: { success: true, message: `Tag "${tag.name}" is not assigned to device` } }, ]; } } // Update the device with the new tags const updateEndpoint = `/api/dcim/devices/${deviceId}/`; const updateBody = { tags: updatedTagIds, }; const response = await apiRequest_1.apiRequest.call(this, 'PATCH', updateEndpoint, updateBody, {}); // Return a more descriptive success message if (action === 'add') { return [ { json: { success: true, message: `Tag "${tag.name}" successfully assigned to device`, device: response, }, }, ]; } else { return [ { json: { success: true, message: `Tag "${tag.name}" successfully removed from device`, device: response, }, }, ]; } } catch (error) { console.log('ERROR in assignTag:', error); if (error.response?.body?.detail) { throw new Error(`NetBox API error: ${error.response.body.detail}`); } else if (error.response?.body?.tags) { throw new Error(`Tags error: ${error.response.body.tags[0]}`); } else { throw error; } } }