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
JavaScript
;
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;
}
}
}