UNPKG

n8n-nodes-arubaclearpass

Version:

n8n community node for Aruba ClearPass API integration with comprehensive identity, policy, and enforcement profile management

481 lines (480 loc) 19.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.listDevices = listDevices; exports.getDevice = getDevice; exports.getDeviceByMac = getDeviceByMac; exports.createDevice = createDevice; exports.updateDevice = updateDevice; exports.updateDeviceByMac = updateDeviceByMac; exports.replaceDevice = replaceDevice; exports.replaceDeviceByMac = replaceDeviceByMac; exports.deleteDevice = deleteDevice; exports.deleteDeviceByMac = deleteDeviceByMac; // methods/Identities/Device.methods.ts const n8n_workflow_1 = require("n8n-workflow"); const apiRequest_1 = require("../../helpers/apiRequest"); const responseFormatter_1 = require("../../helpers/responseFormatter"); /** * List all device accounts */ async function listDevices() { try { const returnAll = this.getNodeParameter('returnAll', 0); const filters = this.getNodeParameter('filters', 0, {}); const endpoint = '/device'; let responseData; if (returnAll) { responseData = await apiRequest_1.apiRequestAllItems.call(this, 'GET', endpoint, {}, filters); } else { const limit = this.getNodeParameter('limit', 0); if (!filters.limit) { filters.limit = limit; } responseData = await apiRequest_1.apiRequest.call(this, 'GET', endpoint, {}, filters); } return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in listDevices'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Get a device account by ID */ async function getDevice() { try { const deviceId = this.getNodeParameter('deviceId', 0); const endpoint = `/device/${deviceId}`; const responseData = await apiRequest_1.apiRequest.call(this, 'GET', endpoint); return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in getDevice'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Get a device account by MAC address */ async function getDeviceByMac() { try { const macAddress = this.getNodeParameter('macAddress', 0); const endpoint = `/device/mac/${macAddress}`; const responseData = await apiRequest_1.apiRequest.call(this, 'GET', endpoint); return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { // Handle 404 errors gracefully (device not found) // This allows workflows to check for existence before creating if (error instanceof Error) { const errorAny = error; // Check for 404 status code in various possible locations const statusCode = errorAny.statusCode || errorAny.httpCode || errorAny.status || (errorAny.cause && (errorAny.cause.statusCode || errorAny.cause.httpCode || errorAny.cause.status)); if (statusCode === 404) { // Return empty array to indicate device not found (allows workflow to continue) return []; } } // For non-404 errors, throw as normal const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in getDeviceByMac'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Create a new device account */ async function createDevice() { try { const body = {}; // Add required fields body.mac = this.getNodeParameter('mac', 0); body.role_id = this.getNodeParameter('role_id', 0); // Add optional fields const additionalFields = this.getNodeParameter('additionalFields', 0, {}); Object.assign(body, additionalFields); // Add custom fields if provided if (additionalFields.customFields) { try { const customFields = JSON.parse(additionalFields.customFields); delete additionalFields.customFields; // Remove from body as we'll add the parsed fields directly // Merge custom fields with the body Object.entries(customFields).forEach(([key, value]) => { body[key] = value; }); } catch (parseError) { throw new Error(`Invalid JSON in customFields: ${parseError.message}`); } } // Get options for query parameters const options = this.getNodeParameter('options', 0, {}); const queryParams = {}; if (options.changeOfAuthorization !== undefined) { queryParams.change_of_authorization = options.changeOfAuthorization; } const endpoint = '/device'; const responseData = await apiRequest_1.apiRequest.call(this, 'POST', endpoint, body, queryParams); return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in createDevice'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Update a device account by ID */ async function updateDevice() { try { const deviceId = this.getNodeParameter('deviceId', 0); const updateFields = this.getNodeParameter('updateFields', 0, {}); if (!Object.keys(updateFields).length) { throw new Error('Please specify at least one field to update'); } const body = { ...updateFields }; // If role_name is provided, look up the role_id (ClearPass requires role_id for updates) if (body.role_name && !body.role_id) { try { const roleName = body.role_name; const roleEndpoint = `/role/name/${encodeURIComponent(roleName)}`; const roleData = await apiRequest_1.apiRequest.call(this, 'GET', roleEndpoint); if (roleData && roleData.id) { body.role_id = roleData.id; // Remove role_name as ClearPass ignores it in PATCH operations delete body.role_name; } else { throw new Error(`Role '${roleName}' not found`); } } catch (roleError) { if (roleError instanceof Error) { throw new Error(`Failed to look up role: ${roleError.message}`); } throw roleError; } } // Handle custom fields if provided if (updateFields.customFields) { try { const customFields = JSON.parse(updateFields.customFields); delete body.customFields; // Remove from body as we'll add the parsed fields directly // Merge custom fields with the body Object.entries(customFields).forEach(([key, value]) => { body[key] = value; }); } catch (parseError) { throw new Error(`Invalid JSON in customFields: ${parseError.message}`); } } // Get options for query parameters const options = this.getNodeParameter('options', 0, {}); const queryParams = {}; if (options.changeOfAuthorization !== undefined) { queryParams.change_of_authorization = options.changeOfAuthorization; } const endpoint = `/device/${deviceId}`; const responseData = await apiRequest_1.apiRequest.call(this, 'PATCH', endpoint, body, queryParams); return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in updateDevice'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Update a device account by MAC address */ async function updateDeviceByMac() { try { const macAddress = this.getNodeParameter('macAddress', 0); const updateFields = this.getNodeParameter('updateFields', 0, {}); if (!Object.keys(updateFields).length) { throw new Error('Please specify at least one field to update'); } const body = { ...updateFields }; // If role_name is provided, look up the role_id (ClearPass requires role_id for updates) if (body.role_name && !body.role_id) { try { const roleName = body.role_name; console.log(`Looking up role by name: ${roleName}`); const roleEndpoint = `/role/name/${encodeURIComponent(roleName)}`; const roleData = await apiRequest_1.apiRequest.call(this, 'GET', roleEndpoint); if (roleData && roleData.id) { console.log(`Found role ID: ${roleData.id} for role: ${roleName}`); body.role_id = roleData.id; // Keep role_name as well - ClearPass validation may require it body.role_name = roleName; } else { throw new Error(`Role '${roleName}' not found - API returned no ID`); } } catch (roleError) { console.log(`Error during role lookup:`, roleError); // Check if it's a 404 (role doesn't exist) const errorAny = roleError; const statusCode = errorAny.statusCode || errorAny.httpCode || errorAny.status || (errorAny.cause && (errorAny.cause.statusCode || errorAny.cause.httpCode || errorAny.cause.status)); if (statusCode === 404) { throw new Error(`Role '${body.role_name}' not found in ClearPass. Please verify the role name exists.`); } if (roleError instanceof Error) { throw new Error(`Failed to look up role '${body.role_name}': ${roleError.message}`); } throw roleError; } } console.log(`Update body before PATCH:`, JSON.stringify(body, null, 2)); // Handle custom fields if provided if (updateFields.customFields) { try { const customFields = JSON.parse(updateFields.customFields); delete body.customFields; // Remove from body as we'll add the parsed fields directly // Merge custom fields with the body Object.entries(customFields).forEach(([key, value]) => { body[key] = value; }); } catch (parseError) { throw new Error(`Invalid JSON in customFields: ${parseError.message}`); } } // Get options for query parameters const options = this.getNodeParameter('options', 0, {}); const queryParams = {}; if (options.changeOfAuthorization !== undefined) { queryParams.change_of_authorization = options.changeOfAuthorization; } const endpoint = `/device/mac/${macAddress}`; console.log(`Sending PATCH to ${endpoint}`); const responseData = await apiRequest_1.apiRequest.call(this, 'PATCH', endpoint, body, queryParams); console.log(`PATCH successful`); return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { console.log(`Error in updateDeviceByMac:`, error); const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in updateDeviceByMac'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Replace a device account by ID */ async function replaceDevice() { try { const deviceId = this.getNodeParameter('deviceId', 0); const body = {}; // Add required fields body.mac = this.getNodeParameter('mac', 0); body.role_id = this.getNodeParameter('role_id', 0); // Add optional fields const additionalFields = this.getNodeParameter('additionalFields', 0, {}); Object.assign(body, additionalFields); // Add custom fields if provided if (additionalFields.customFields) { try { const customFields = JSON.parse(additionalFields.customFields); delete body.customFields; // Remove from body as we'll add the parsed fields directly // Merge custom fields with the body Object.entries(customFields).forEach(([key, value]) => { body[key] = value; }); } catch (parseError) { throw new Error(`Invalid JSON in customFields: ${parseError.message}`); } } // Get options for query parameters const options = this.getNodeParameter('options', 0, {}); const queryParams = {}; if (options.changeOfAuthorization !== undefined) { queryParams.change_of_authorization = options.changeOfAuthorization; } const endpoint = `/device/${deviceId}`; const responseData = await apiRequest_1.apiRequest.call(this, 'PUT', endpoint, body, queryParams); return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in replaceDevice'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Replace a device account by MAC address */ async function replaceDeviceByMac() { try { const macAddress = this.getNodeParameter('macAddress', 0); const body = {}; // Add required fields body.mac = this.getNodeParameter('mac', 0); body.role_id = this.getNodeParameter('role_id', 0); // Add optional fields const additionalFields = this.getNodeParameter('additionalFields', 0, {}); Object.assign(body, additionalFields); // Add custom fields if provided if (additionalFields.customFields) { try { const customFields = JSON.parse(additionalFields.customFields); delete body.customFields; // Remove from body as we'll add the parsed fields directly // Merge custom fields with the body Object.entries(customFields).forEach(([key, value]) => { body[key] = value; }); } catch (parseError) { throw new Error(`Invalid JSON in customFields: ${parseError.message}`); } } // Get options for query parameters const options = this.getNodeParameter('options', 0, {}); const queryParams = {}; if (options.changeOfAuthorization !== undefined) { queryParams.change_of_authorization = options.changeOfAuthorization; } const endpoint = `/device/mac/${macAddress}`; const responseData = await apiRequest_1.apiRequest.call(this, 'PUT', endpoint, body, queryParams); return responseFormatter_1.formatResponse.call(this, responseData); } catch (error) { const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in replaceDeviceByMac'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Delete a device account by ID */ async function deleteDevice() { try { const deviceId = this.getNodeParameter('deviceId', 0); // Get options for query parameters const options = this.getNodeParameter('options', 0, {}); const queryParams = {}; if (options.changeOfAuthorization !== undefined) { queryParams.change_of_authorization = options.changeOfAuthorization; } const endpoint = `/device/${deviceId}`; await apiRequest_1.apiRequest.call(this, 'DELETE', endpoint, {}, queryParams); return [{ json: { success: true } }]; } catch (error) { const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in deleteDevice'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } } /** * Delete a device account by MAC address */ async function deleteDeviceByMac() { try { const macAddress = this.getNodeParameter('macAddress', 0); // Get options for query parameters const options = this.getNodeParameter('options', 0, {}); const queryParams = {}; if (options.changeOfAuthorization !== undefined) { queryParams.change_of_authorization = options.changeOfAuthorization; } const endpoint = `/device/mac/${macAddress}`; await apiRequest_1.apiRequest.call(this, 'DELETE', endpoint, {}, queryParams); return [{ json: { success: true } }]; } catch (error) { const errorObject = {}; if (error instanceof Error) { errorObject.message = error.message; if (error.stack) { errorObject.stackTrace = error.stack; } } else { errorObject.message = 'Unknown error in deleteDeviceByMac'; } throw new n8n_workflow_1.NodeApiError(this.getNode(), errorObject); } }