UNPKG

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
"use strict"; 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; } }