n8n-nodes-netbox
Version:
n8n community node for NetBox API integration with comprehensive DCIM, IPAM, and data center management operations
309 lines (308 loc) • 13.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.listIPAddresses = listIPAddresses;
exports.getIPAddress = getIPAddress;
exports.createIPAddress = createIPAddress;
exports.updateIPAddress = updateIPAddress;
exports.deleteIPAddress = deleteIPAddress;
const apiRequest_1 = require("../../../helpers/apiRequest");
const responseFormatter_1 = require("../../../helpers/responseFormatter");
const resourceLookup_1 = require("../../../helpers/resourceLookup");
async function listIPAddresses() {
try {
// Get pagination parameters
const returnAll = this.getNodeParameter('returnAll', 0, false);
// Get filters
const filters = this.getNodeParameter('filters', 0, {});
// Prepare query parameters
const queryParams = { ...filters };
// Handle array parameters (comma-separated values)
[
'address',
'assigned_object_id',
'contact',
'contact_group',
'contact_role',
'device',
'device_id',
'interface',
'interface_id',
'parent',
'role',
'status',
'tag',
'tenant',
'tenant_id',
'virtual_machine',
'virtual_machine_id',
'vminterface',
'vminterface_id',
'vrf',
'vrf_id',
].forEach((param) => {
if (queryParams[param] && typeof queryParams[param] === 'string') {
// Convert comma-separated strings to arrays for API
if (queryParams[param].includes(',')) {
queryParams[param] = queryParams[param].split(',').map((item) => item.trim());
}
}
});
console.log('List IP Addresses Query Params:', queryParams);
let responseData;
if (returnAll === true) {
responseData = await apiRequest_1.apiRequestAllItems.call(this, 'GET', '/api/ipam/ip-addresses/', {}, queryParams);
return responseFormatter_1.formatResponse.call(this, responseData);
}
else {
const limit = this.getNodeParameter('limit', 0, 50);
queryParams.limit = limit;
responseData = await apiRequest_1.apiRequest.call(this, 'GET', '/api/ipam/ip-addresses/', {}, queryParams);
return responseFormatter_1.formatResponse.call(this, responseData);
}
}
catch (error) {
console.log('ERROR in listIPAddresses:', error);
throw error;
}
}
async function getIPAddress() {
try {
const ipAddressIdOrAddress = this.getNodeParameter('ipAddressId', 0);
// Check if it's numeric (ID) or an IP address
let endpoint;
if (!isNaN(Number(ipAddressIdOrAddress))) {
// If it's a numeric ID, use it directly
endpoint = `/api/ipam/ip-addresses/${ipAddressIdOrAddress}/`;
}
else {
// If it's not numeric, try to find by IP address
console.log(`Attempting to find IP address: ${ipAddressIdOrAddress}`);
const filters = {
address: ipAddressIdOrAddress,
};
const ipAddresses = await apiRequest_1.apiRequest.call(this, 'GET', '/api/ipam/ip-addresses/', {}, filters);
if (ipAddresses.results && ipAddresses.results.length > 0) {
// Found a matching IP address, use its ID
const ipAddress = ipAddresses.results[0];
console.log(`Found IP address with ID: ${ipAddress.id}`);
endpoint = `/api/ipam/ip-addresses/${ipAddress.id}/`;
}
else {
throw new Error(`Could not find IP address: ${ipAddressIdOrAddress}`);
}
}
console.log(`Getting IP address with endpoint: ${endpoint}`);
const response = await apiRequest_1.apiRequest.call(this, 'GET', endpoint, {}, {});
return responseFormatter_1.formatResponse.call(this, response);
}
catch (error) {
console.log('ERROR in getIPAddress:', error);
throw error;
}
}
async function createIPAddress() {
try {
const useRawJson = this.getNodeParameter('useRawJson', 0, false);
let ipAddressData;
if (useRawJson) {
// Use raw JSON input
const ipAddressDataRaw = this.getNodeParameter('ipAddressData', 0);
if (typeof ipAddressDataRaw === 'string') {
try {
ipAddressData = JSON.parse(ipAddressDataRaw);
}
catch (parseError) {
throw new Error(`Invalid JSON in IP address data: ${parseError.message}`);
}
}
else {
ipAddressData = ipAddressDataRaw;
}
}
else {
// Build from individual fields
const address = this.getNodeParameter('address', 0);
const additionalFields = this.getNodeParameter('additionalFields', 0, {});
ipAddressData = {
address,
};
// Add additional fields only if they have values
Object.keys(additionalFields).forEach((key) => {
const value = additionalFields[key];
if (value !== undefined && value !== null && value !== '') {
ipAddressData[key] = value;
}
});
// Handle nested object lookups using the resourceLookup helper
const nestedFields = ['vrf', 'tenant'];
for (const field of nestedFields) {
if (ipAddressData[field] && typeof ipAddressData[field] === 'string') {
try {
const resourceType = field === 'vrf' ? 'vrfs' : `${field}s`;
const domain = field === 'tenant' ? 'tenancy' : 'ipam';
console.log(`Looking up ${field}: ${ipAddressData[field]} in domain ${domain}`);
const resourceId = await resourceLookup_1.lookupResourceByName.call(this, resourceType, ipAddressData[field], domain);
console.log(`Found ${field} ID: ${resourceId}`);
ipAddressData[field] = resourceId;
}
catch (lookupError) {
console.log(`Warning: Could not lookup ${field}: ${lookupError.message}`);
// Continue without the field rather than failing
delete ipAddressData[field];
}
}
}
// Handle tags - convert comma-separated string to array of objects
if (ipAddressData.tags && typeof ipAddressData.tags === 'string') {
const tagNames = ipAddressData.tags.split(',').map((tag) => tag.trim());
ipAddressData.tags = tagNames.map((name) => ({ name }));
}
// Clean up any empty or zero values that might cause validation issues
const fieldsToCheck = [
'vrf',
'tenant',
'assigned_object_type',
'assigned_object_id',
'nat_inside',
'description',
'dns_name',
'comments',
];
fieldsToCheck.forEach((field) => {
if (ipAddressData[field] === '' ||
ipAddressData[field] === 0 ||
ipAddressData[field] === null) {
delete ipAddressData[field];
}
});
}
// Validate required fields
if (!ipAddressData.address) {
throw new Error('Address field is required');
}
console.log('Final IP address data being sent:', JSON.stringify(ipAddressData, null, 2));
const endpoint = '/api/ipam/ip-addresses/';
const response = await apiRequest_1.apiRequest.call(this, 'POST', endpoint, ipAddressData, {});
return responseFormatter_1.formatResponse.call(this, response);
}
catch (error) {
console.log('ERROR in createIPAddress:', error);
throw error;
}
}
async function updateIPAddress() {
try {
const ipAddressIdOrAddress = this.getNodeParameter('ipAddressId', 0);
const useRawJson = this.getNodeParameter('useRawJson', 0, false);
let ipAddressData;
if (useRawJson) {
// Use raw JSON input
const ipAddressDataRaw = this.getNodeParameter('ipAddressData', 0);
if (typeof ipAddressDataRaw === 'string') {
try {
ipAddressData = JSON.parse(ipAddressDataRaw);
}
catch (parseError) {
throw new Error(`Invalid JSON in IP address data: ${parseError.message}`);
}
}
else {
ipAddressData = ipAddressDataRaw;
}
}
else {
// Build from individual fields
const updateFields = this.getNodeParameter('updateFields', 0, {});
ipAddressData = { ...updateFields };
// Handle nested object lookups using the resourceLookup helper
const nestedFields = ['vrf', 'tenant'];
for (const field of nestedFields) {
if (updateFields[field] && typeof updateFields[field] === 'string') {
try {
const resourceType = field === 'vrf' ? 'vrfs' : `${field}s`;
const domain = field === 'tenant' ? 'tenancy' : 'ipam';
const resourceId = await resourceLookup_1.lookupResourceByName.call(this, resourceType, updateFields[field], domain);
ipAddressData[field] = resourceId;
}
catch (lookupError) {
console.log(`Warning: Could not lookup ${field}: ${lookupError.message}`);
// Continue without the field rather than failing
delete ipAddressData[field];
}
}
}
// Handle tags - convert comma-separated string to array of objects
if (updateFields.tags && typeof updateFields.tags === 'string') {
const tagNames = updateFields.tags.split(',').map((tag) => tag.trim());
ipAddressData.tags = tagNames.map((name) => ({ name }));
}
}
// Determine the actual IP address ID
let ipAddressId = ipAddressIdOrAddress;
// If not numeric, try to find by IP address
if (!isNaN(Number(ipAddressIdOrAddress))) {
ipAddressId = ipAddressIdOrAddress; // It's already a numeric ID
}
else {
// Try to find the IP address
console.log(`Attempting to find IP address: ${ipAddressIdOrAddress}`);
const filters = {
address: ipAddressIdOrAddress,
};
const ipAddresses = await apiRequest_1.apiRequest.call(this, 'GET', '/api/ipam/ip-addresses/', {}, filters);
if (ipAddresses.results && ipAddresses.results.length > 0) {
// Found a matching IP address, use its ID
ipAddressId = ipAddresses.results[0].id;
console.log(`Found IP address with ID: ${ipAddressId}`);
}
else {
throw new Error(`Could not find IP address: ${ipAddressIdOrAddress}`);
}
}
const endpoint = `/api/ipam/ip-addresses/${ipAddressId}/`;
const response = await apiRequest_1.apiRequest.call(this, 'PATCH', endpoint, ipAddressData, {});
return responseFormatter_1.formatResponse.call(this, response);
}
catch (error) {
console.log('ERROR in updateIPAddress:', error);
throw error;
}
}
async function deleteIPAddress() {
try {
const ipAddressIdOrAddress = this.getNodeParameter('ipAddressId', 0);
// Determine the actual IP address ID
let ipAddressId = ipAddressIdOrAddress;
// If not numeric, try to find by IP address
if (!isNaN(Number(ipAddressIdOrAddress))) {
ipAddressId = ipAddressIdOrAddress; // It's already a numeric ID
}
else {
// Try to find the IP address
console.log(`Attempting to find IP address: ${ipAddressIdOrAddress}`);
const filters = {
address: ipAddressIdOrAddress,
};
const ipAddresses = await apiRequest_1.apiRequest.call(this, 'GET', '/api/ipam/ip-addresses/', {}, filters);
if (ipAddresses.results && ipAddresses.results.length > 0) {
// Found a matching IP address, use its ID
ipAddressId = ipAddresses.results[0].id;
console.log(`Found IP address with ID: ${ipAddressId}`);
}
else {
throw new Error(`Could not find IP address: ${ipAddressIdOrAddress}`);
}
}
const endpoint = `/api/ipam/ip-addresses/${ipAddressId}/`;
await apiRequest_1.apiRequest.call(this, 'DELETE', endpoint, {}, {});
return [
{
json: { success: true, message: `IP address with ID ${ipAddressId} successfully deleted` },
},
];
}
catch (error) {
console.log('ERROR in deleteIPAddress:', error);
throw error;
}
}