n8n-nodes-awx
Version:
n8n node to interact with Ansible AWX/Tower with improved type safety
998 lines (995 loc) • 46.8 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatResponse = void 0;
exports.getAwxResources = getAwxResources;
exports.getAwxResource = getAwxResource;
exports.createAwxResource = createAwxResource;
exports.launchAwxTemplate = launchAwxTemplate;
exports.updateAwxResource = updateAwxResource;
exports.deleteAwxResourceWithLogging = deleteAwxResourceWithLogging;
exports.cancelAwxJobGeneric = cancelAwxJobGeneric;
exports.syncAwxResource = syncAwxResource;
exports.deleteAwxResource = deleteAwxResource;
exports.executeResourceHandler = executeResourceHandler;
exports.processResourceResult = processResourceResult;
exports.handleResourceOperation = handleResourceOperation;
exports.getAwxResourceById = getAwxResourceById;
exports.getAwxJobOutput = getAwxJobOutput;
exports.executeAwxToolOperation = executeAwxToolOperation;
exports.resolveResourceParameters = resolveResourceParameters;
exports.createParameterResolutionErrorMessage = createParameterResolutionErrorMessage;
exports.createParameterDiagnosticReport = createParameterDiagnosticReport;
exports.executeProject = executeProject;
exports.executeWorkflowJob = executeWorkflowJob;
exports.executeJobTemplate = executeJobTemplate;
exports.executeWorkflowJobTemplate = executeWorkflowJobTemplate;
const WorkflowJobTemplateResources_1 = require("../../src/resources/WorkflowJobTemplateResources");
const n8n_workflow_1 = require("n8n-workflow");
const GenericFunctions_1 = require("./GenericFunctions");
async function getAwxResources(resourcePath, fetchMode = 'firstPage', query = {}, options = {
timeout: null,
waitForCompletion: null,
pollInterval: null,
maxRetries: null,
forceRefresh: null,
}) {
if (fetchMode === 'allPages') {
return await GenericFunctions_1.awxApiRequestAllItems.call(this, 'GET', resourcePath, {}, query, options);
}
else {
const response = await GenericFunctions_1.awxApiRequest.call(this, 'GET', resourcePath, {}, query, options);
console.log(`[AWX] getAwxResources response type: ${typeof response}, isArray: ${Array.isArray(response)}`, response ? Object.keys(response) : 'null');
if (response && typeof response === 'object' && 'results' in response) {
console.log(`[AWX] Collection response found with ${response.results.length} results`);
return response.results;
}
if (response && typeof response === 'object' && 'id' in response) {
console.log('[AWX] Single-item response found with ID:', response.id);
return [response];
}
if (Array.isArray(response)) {
return response;
}
if (response && typeof response === 'object' && Object.keys(response).length > 0) {
console.log('[AWX] Unknown object response format, treating as single item');
return [response];
}
console.log('[AWX] No valid response data, returning empty array');
return [];
}
}
async function getAwxResource(resourceType, identifier, itemIndex = 0) {
if (!identifier.id && !identifier.name) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Either ID or Name must be provided to get a ${resourceType}.`, { itemIndex });
}
let resolvedResourceId;
try {
resolvedResourceId = await GenericFunctions_1.getResourceById.call(this, resourceType, identifier.id ? String(identifier.id) : undefined, identifier.name, itemIndex);
console.log(`AWX Node: Resolved ${resourceType} identifier to ID ${resolvedResourceId}`);
}
catch (error) {
console.error(`AWX Node: Error resolving ID for ${resourceType} with identifier ${JSON.stringify(identifier)}:`, error);
if (error instanceof n8n_workflow_1.NodeOperationError) {
throw error;
}
const errorMessage = error instanceof Error ? error.message : String(error);
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error resolving ID for ${resourceType}: ${errorMessage}`, { itemIndex });
}
const resourceEndpoint = `/${resourceType}/${resolvedResourceId}/`;
console.log(`AWX Node: Fetching ${resourceType} with ID ${resolvedResourceId}`);
try {
const resource = await GenericFunctions_1.awxApiRequest.call(this, 'GET', resourceEndpoint, {});
return resource;
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error(`AWX Node: Error fetching ${resourceType} with ID ${resolvedResourceId}:`, error);
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error fetching ${resourceType} with ID ${resolvedResourceId}: ${errorMessage}`, { itemIndex });
}
}
async function createAwxResource(endpoint, bodyData, itemIndex = 0) {
try {
console.log(`AWX Node: POST request to ${endpoint} with data:`, JSON.stringify(bodyData));
const response = await GenericFunctions_1.awxApiRequest.call(this, 'POST', endpoint, bodyData);
return response;
}
catch (error) {
console.error(`AWX Node: Error in POST request to ${endpoint}:`, error);
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error creating AWX resource: ${error.message}`, { itemIndex });
}
}
async function launchAwxTemplate(resourceType, templateId, payload) {
const endpoint = `/${resourceType}/${templateId}/launch/`;
return createAwxResource.call(this, endpoint, payload);
}
async function updateAwxResource(endpoint, bodyData, itemIndex = 0) {
try {
console.log(`AWX Node: PATCH request to ${endpoint} with data:`, JSON.stringify(bodyData));
const response = await GenericFunctions_1.awxApiRequest.call(this, 'PATCH', endpoint, bodyData);
return response;
}
catch (error) {
console.error(`AWX Node: Error in PATCH request to ${endpoint}:`, error);
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error updating AWX resource: ${error.message}`, { itemIndex });
}
}
async function deleteAwxResourceWithLogging(endpoint, itemIndex = 0) {
try {
console.log(`AWX Node: DELETE request to ${endpoint}`);
await GenericFunctions_1.awxApiRequest.call(this, 'DELETE', endpoint, {});
console.log(`AWX Node: Successfully deleted resource at ${endpoint}`);
}
catch (error) {
console.error(`AWX Node: Error in DELETE request to ${endpoint}:`, error);
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error deleting AWX resource: ${error.message}`, { itemIndex });
}
}
async function cancelAwxJobGeneric(jobType, jobId, itemIndex = 0) {
const cancelEndpoint = `/${jobType}/${jobId}/cancel/`;
try {
const requestOptions = {
timeout: null,
waitForCompletion: null,
pollInterval: null,
maxRetries: null,
forceRefresh: null,
itemIndex,
};
return await GenericFunctions_1.awxApiRequest.call(this, 'POST', cancelEndpoint, {}, {}, requestOptions);
}
catch (error) {
console.error(`[AWX] Failed to cancel ${jobType} job ${jobId}: ${error.message}`);
throw error;
}
}
async function syncAwxResource(endpoint, itemIndex = 0) {
try {
console.log(`AWX Node: POST request to ${endpoint} to trigger sync`);
const response = await GenericFunctions_1.awxApiRequest.call(this, 'POST', endpoint, {});
return response;
}
catch (error) {
console.error(`AWX Node: Error in POST request to ${endpoint}:`, error);
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error syncing AWX resource: ${error.message}`, { itemIndex });
}
}
async function deleteAwxResource(endpoint) {
try {
const credentials = await this.getCredentials('awxApi');
const options = {
url: `${credentials.baseUrl}${endpoint}`,
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${credentials.apiKey}`
},
json: true
};
await this.helpers.httpRequest(options);
return { success: true };
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
}
}
const formatResponse = function (data) {
if (Array.isArray(data)) {
return [data.map(item => ({ json: item }))];
}
else {
return [[{ json: data }]];
}
};
exports.formatResponse = formatResponse;
async function executeResourceHandler(context, resourceType, action, handler, itemIndex) {
try {
return await handler.call(context, action, itemIndex !== undefined ? itemIndex : 0);
}
catch (error) {
throw new Error(`Error in ${resourceType} operation: ${error.message}`);
}
}
function processResourceResult(result) {
if (result && result.length > 0 && result[0].length > 0) {
return result[0][0].json;
}
else {
return { success: true, message: 'Operation completed but no data returned' };
}
}
async function handleResourceOperation(context, resource, action, handler, specialParams = {}) {
const paramOrder = specialParams.paramOrder || 'standard';
const needsItemIndex = specialParams.needsItemIndex !== undefined ? specialParams.needsItemIndex : false;
const returnRaw = specialParams.returnRaw !== undefined ? specialParams.returnRaw : false;
let wrapperFunction;
if (paramOrder === 'itemIndexFirst') {
wrapperFunction = async function (action, itemIndex) {
return handler.call(this, itemIndex !== undefined ? itemIndex : 0, action);
};
}
else if (needsItemIndex) {
wrapperFunction = async function (action, itemIndex) {
return handler.call(this, action, itemIndex !== undefined ? itemIndex : 0);
};
}
else {
wrapperFunction = async function (action) {
return handler.call(this, action);
};
}
const result = await executeResourceHandler(context, resource, action, wrapperFunction);
return returnRaw ? result : processResourceResult(result);
}
async function getAwxResourceById(resourceType, id, itemIndex = 0) {
try {
const formattedResourceType = resourceType.replace(/s$/, '') + 's';
const endpoint = `/${formattedResourceType}/${id}/`;
console.log(`AWX Node: Fetching ${resourceType} with ID ${id} from endpoint ${endpoint}`);
const requestOptions = {
timeout: null,
waitForCompletion: null,
pollInterval: null,
maxRetries: null,
forceRefresh: null,
itemIndex,
};
const response = await GenericFunctions_1.awxApiRequest.call(this, 'GET', endpoint, {}, {}, requestOptions);
if (!response) {
throw new Error(`No response received when fetching ${resourceType} with ID ${id}`);
}
console.log(`AWX Node: Successfully retrieved ${resourceType} with ID ${id}`);
return response;
}
catch (error) {
console.error(`AWX Node: Error fetching ${resourceType} with ID ${id}:`, error);
if (error.statusCode === 404 || (error.response && error.response.statusCode === 404)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${resourceType} with ID ${id} not found`, { itemIndex });
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error fetching ${resourceType} with ID ${id}: ${error.message}`, { itemIndex });
}
}
async function getAwxJobOutput(resourceType, id, itemIndex = 0, jobData) {
try {
const endpointFormats = [
`/${resourceType}/${id}/stdout/`,
`/${resourceType}/${id}/stdout/?format=txt`,
`/${resourceType}/${id}/stdout`,
`/${resourceType}/${id}/?format=txt`,
];
let output = '';
let succeeded = false;
for (const endpoint of endpointFormats) {
try {
console.log(`AWX Node: Trying to fetch ${resourceType} output with endpoint ${endpoint}`);
const requestOptions = {
timeout: null,
waitForCompletion: null,
pollInterval: null,
maxRetries: null,
forceRefresh: null,
itemIndex,
};
const response = await GenericFunctions_1.awxApiRequest.call(this, 'GET', endpoint, {}, {}, requestOptions);
if (typeof response === 'string') {
output = response;
succeeded = true;
console.log(`AWX Node: Retrieved ${resourceType} output as string (${output.length} characters)`);
break;
}
else if (response && typeof response === 'object') {
const responseObj = response;
const outputFields = ['content', 'result', 'stdout', 'output'];
for (const field of outputFields) {
if (responseObj[field] && typeof responseObj[field] === 'string') {
output = String(responseObj[field]);
succeeded = true;
console.log(`AWX Node: Retrieved ${resourceType} output from ${field} field (${output.length} characters)`);
break;
}
}
if (succeeded)
break;
}
}
catch (innerError) {
console.log(`[AWX] Failed to fetch output with endpoint ${endpoint}: ${innerError.message}`);
}
}
if (succeeded) {
return output;
}
if (!jobData) {
console.log(`AWX Node: Fetching ${resourceType} data to find output`);
try {
const data = await getAwxResourceById.call(this, resourceType, String(id), itemIndex);
console.log(`AWX Node: Got ${resourceType} data, checking for output fields`);
const outputFields = ['result_stdout', 'stdout', 'output', 'result', 'result_stdout_file', 'task_output'];
for (const field of outputFields) {
if (data[field] && typeof data[field] === 'string') {
output = String(data[field]);
console.log(`AWX Node: Retrieved ${resourceType} output from ${field} field (${output.length} characters)`);
return output;
}
}
}
catch (dataError) {
console.error(`[AWX] Failed to fetch ${resourceType} data for output: ${dataError.message}`);
}
}
else {
const outputFields = ['result_stdout', 'stdout', 'output', 'result', 'result_stdout_file', 'task_output'];
for (const field of outputFields) {
if (jobData[field] && typeof jobData[field] === 'string') {
output = String(jobData[field]);
console.log(`AWX Node: Retrieved ${resourceType} output from ${field} field (${output.length} characters)`);
return output;
}
}
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to retrieve job output after multiple attempts');
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error getting AWX job output: ${error.message}`);
}
}
async function executeAwxToolOperation(context) {
var _a, _b;
console.log('AWX Node: executeAwxToolOperation called');
try {
const inputData = context.getInputData();
if (inputData && inputData[0] && inputData[0].json) {
console.log('AWX Node: Raw input data before normalization:', JSON.stringify(inputData[0].json));
}
else {
console.log('AWX Node: No valid input data to normalize');
}
}
catch (error) {
console.error('AWX Node: Error logging raw input data:', error);
}
try {
const resource = context.getNodeParameter('resource', 0);
const action = context.getNodeParameter('action', 0);
console.log(`AWX Tool: Executing operation - Resource: ${resource}, Action: ${action}`);
try {
const inputData = ((_a = context.getInputData()[0]) === null || _a === void 0 ? void 0 : _a.json) || {};
console.log(`AWX Tool: Raw input data received: ${JSON.stringify(inputData, null, 2)}`);
}
catch (error) {
console.error(`AWX Tool: Error logging input data: ${error.message}`);
}
if (resource === 'diagnostic' && action === 'parameters') {
const diagnosticReport = {
timestamp: new Date().toISOString(),
message: 'AWX Tool Parameter Diagnostic',
parameterMappings: {
jobTemplate: {
idKeys: ['Job_Template_ID', 'Template_ID', 'jobTemplateId', 'jobTemplateID', 'templateId', 'id'],
nameKeys: ['Template_Name', 'templateName', 'name']
},
inventory: {
idKeys: ['Inventory_ID', 'inventoryId', 'inventoryID', 'id'],
nameKeys: ['Inventory_Name', 'inventoryName', 'name']
},
host: {
idKeys: ['Host_ID', 'hostId', 'hostID', 'id'],
nameKeys: ['Host_Name', 'hostName', 'name']
},
group: {
idKeys: ['Group_ID', 'groupId', 'groupID', 'id'],
nameKeys: ['Group_Name', 'groupName', 'name']
}
},
rawInput: {},
normalizedParameters: {}
};
const inputData = ((_b = context.getInputData()[0]) === null || _b === void 0 ? void 0 : _b.json) || {};
if (inputData) {
const normalizedParams = {};
for (const [key, value] of Object.entries(inputData)) {
let newKey = key;
if (key.includes('_')) {
newKey = key.toLowerCase().replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
}
if (key === 'Job_Template_ID')
newKey = 'jobTemplateId';
if (key === 'jobTemplateID')
newKey = 'jobTemplateId';
if (key === 'Template_Name')
newKey = 'templateName';
if (key === 'Inventory_ID')
newKey = 'inventoryID';
if (key === 'Inventory_Name')
newKey = 'inventoryName';
normalizedParams[newKey] = value;
console.log(`AWX Node: Parameter transformation: ${key} → ${newKey}`);
}
diagnosticReport.normalizedParameters = normalizedParams;
}
return [[{ json: diagnosticReport }]];
}
const { handleProjectOperations } = await Promise.resolve().then(() => __importStar(require('../resources/ProjectResources')));
const { handleInventoryOperations } = await Promise.resolve().then(() => __importStar(require('../resources/InventoryResources')));
const { handleGroupOperations } = await Promise.resolve().then(() => __importStar(require('../resources/GroupResources')));
const { handleHostOperations } = await Promise.resolve().then(() => __importStar(require('../resources/HostResources')));
const { handleJobOperations } = await Promise.resolve().then(() => __importStar(require('../resources/JobResources')));
const { handleJobTemplateOperations } = await Promise.resolve().then(() => __importStar(require('../resources/JobTemplateResources')));
const { handleWorkflowJobTemplateOperations, handleWorkflowJobOperations } = await Promise.resolve().then(() => __importStar(require('../resources/WorkflowJobTemplateResources')));
switch (resource) {
case 'project':
return await handleResourceOperation(context, 'project', action, handleProjectOperations, { returnRaw: true });
case 'inventory':
return await handleResourceOperation(context, 'inventory', action, handleInventoryOperations, { returnRaw: true });
case 'group':
return await handleResourceOperation(context, 'group', action, handleGroupOperations, { returnRaw: true });
case 'host':
return await handleResourceOperation(context, 'host', action, handleHostOperations, { returnRaw: true });
case 'jobTemplate':
return await handleResourceOperation(context, 'jobTemplate', action, handleJobTemplateOperations, { returnRaw: true });
case 'job':
return await handleResourceOperation(context, 'job', action, handleJobOperations, { returnRaw: true });
case 'workflowJobTemplate':
return await handleResourceOperation(context, 'workflowJobTemplate', action, handleWorkflowJobTemplateOperations, { returnRaw: true });
case 'workflowJob':
return await handleResourceOperation(context, 'workflowJob', action, handleWorkflowJobOperations, { returnRaw: true });
default:
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Unsupported resource type: ${resource}`);
}
}
catch (error) {
console.error(`AWX Node: Error in executeAwxToolOperation: ${error.message}`);
throw error;
}
}
function resolveResourceParameters(resourceType, idKeys, nameKeys, logPrefix = '') {
var _a;
console.log(`=== ${logPrefix || resourceType.toUpperCase()} - PARAMETER RESOLUTION ===`);
console.log(`Looking for ID keys: ${JSON.stringify(idKeys)}`);
console.log(`Looking for Name keys: ${JSON.stringify(nameKeys)}`);
let id = '';
let name = '';
console.log('Checking node parameters (UI-based):');
for (const key of idKeys) {
try {
id = this.getNodeParameter(key, 0, '');
if (id) {
console.log(`✓ Found ${key} in node parameters: ${id}`);
break;
}
else {
console.log(`✗ ${key} exists in node parameters but is empty`);
}
}
catch (error) {
console.log(`✗ Parameter ${key} not found in node parameters`);
}
}
if (!id) {
for (const key of nameKeys) {
try {
name = this.getNodeParameter(key, 0, '');
if (name) {
console.log(`✓ Found ${key} in node parameters: ${name}`);
break;
}
else {
console.log(`✗ ${key} exists in node parameters but is empty`);
}
}
catch (error) {
console.log(`✗ Parameter ${key} not found in node parameters`);
}
}
}
if (!id && !name) {
console.log('Checking execution data parameters (for AI agent tools):');
const inputData = this.getInputData()[0];
console.log(`Input data available: ${inputData ? 'Yes' : 'No'}`);
if (inputData) {
console.log(`Input data type: ${typeof inputData.json}`);
console.log('Full input data:', JSON.stringify(inputData.json, null, 2));
const directParameters = inputData.json || {};
const nestedParameters = ((_a = inputData.json) === null || _a === void 0 ? void 0 : _a.parameters) || {};
console.log('Direct parameters available:', Object.keys(directParameters).length > 0 ? 'Yes' : 'No');
console.log('Nested parameters available:', Object.keys(nestedParameters).length > 0 ? 'Yes' : 'No');
const allPossibleParams = [directParameters, nestedParameters];
for (const params of allPossibleParams) {
console.log('Checking parameter set:', JSON.stringify(params, null, 2));
for (const key of idKeys) {
if (params[key] !== undefined) {
id = params[key];
console.log(`✓ Found ${key} in parameters: ${id}`);
break;
}
else {
console.log(`✗ ${key} not found in this parameter set`);
}
}
if (id)
break;
if (!id) {
for (const key of nameKeys) {
if (params[key] !== undefined) {
name = params[key];
console.log(`✓ Found ${key} in parameters: ${name}`);
break;
}
else {
console.log(`✗ ${key} not found in this parameter set`);
}
}
if (name)
break;
}
}
}
}
console.log(`Final parameter values - ID: ${id || '(not provided)'}, Name: ${name || '(not provided)'}`);
return { id, name };
}
function createParameterResolutionErrorMessage(resourceType, idKeys, nameKeys) {
var _a;
const inputData = ((_a = this.getInputData()[0]) === null || _a === void 0 ? void 0 : _a.json) || {};
return `Either ${resourceType} ID or Name must be provided.
Expected parameters:
- ID keys: ${JSON.stringify(idKeys)}
- Name keys: ${JSON.stringify(nameKeys)}
Received parameters: ${JSON.stringify(inputData, null, 2)}
After normalization, no matching ID or name parameter was found.`;
}
function createParameterDiagnosticReport(resourceType, idKeys, nameKeys) {
var _a;
const inputData = ((_a = this.getInputData()[0]) === null || _a === void 0 ? void 0 : _a.json) || {};
const parameters = inputData.parameters || {};
const availableDirectParams = Object.keys(inputData);
const availableNestedParams = Object.keys(parameters);
const foundIdKeys = idKeys.filter(key => inputData[key] !== undefined || parameters[key] !== undefined);
const foundNameKeys = nameKeys.filter(key => inputData[key] !== undefined || parameters[key] !== undefined);
return {
timestamp: new Date().toISOString(),
resourceType,
expectedParameters: {
idKeys,
nameKeys
},
receivedParameters: {
directParameters: inputData,
nestedParameters: parameters
},
parameterAnalysis: {
availableDirectParams,
availableNestedParams,
foundIdKeys,
foundNameKeys,
missingIdKeys: idKeys.filter(key => !foundIdKeys.includes(key)),
missingNameKeys: nameKeys.filter(key => !foundNameKeys.includes(key))
}
};
}
async function executeProject(inputs) {
if (inputs.resource !== 'project') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid resource type '${inputs.resource}' for project operation`);
}
try {
switch (inputs.action) {
case 'get': {
const response = await getAwxResources.call(this, `/projects/${inputs.id}/`);
const projectData = Array.isArray(response) && response.length > 0 ?
(typeof response[0] === 'string' ? JSON.parse(response[0]) : response[0]) :
response;
return [[{
json: projectData,
pairedItem: { item: 0 }
}]];
}
case 'list': {
const projects = await getAwxResources.call(this, '/projects/');
return [projects.map((project, i) => {
const itemData = typeof project === 'string'
? JSON.parse(project)
: project;
return {
json: itemData,
pairedItem: { item: i }
};
})];
}
case 'update': {
const response = await getAwxResources.call(this, `/projects/${inputs.id}/`);
const projectData = Array.isArray(response) && response.length > 0 ?
(typeof response[0] === 'string' ? JSON.parse(response[0]) : response[0]) :
response;
return [[{
json: projectData,
pairedItem: { item: 0 }
}]];
}
case 'delete': {
await deleteAwxResource.call(this, `/projects/${inputs.id}/`);
return [[{
json: { success: true },
pairedItem: { item: 0 }
}]];
}
default:
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported project action: ${inputs.action}`);
}
}
catch (error) {
if (error instanceof Error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Project operation failed: ${error.message}`);
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Unknown error during project operation');
}
}
async function executeWorkflowJob(inputs) {
try {
let responseData;
const returnData = [];
switch (inputs.action) {
case 'get': {
if (!inputs.jobId)
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Workflow Job ID required');
responseData = await GenericFunctions_1.awxApiRequest.call(this, 'GET', `/workflow_jobs/${inputs.jobId}/`);
returnData.push(responseData);
break;
}
case 'list': {
const response = await GenericFunctions_1.awxApiRequest.call(this, 'GET', '/workflow_jobs/');
returnData.push(...(Array.isArray(response.results) ? response.results : [response]));
break;
}
case 'delete': {
if (!inputs.jobId)
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Workflow Job ID required');
await deleteAwxResource.call(this, `/workflow_jobs/${inputs.jobId}/`);
returnData.push({ success: true });
break;
}
default:
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Action '${inputs.action}' not implemented for workflow jobs`);
}
return [this.helpers.returnJsonArray(returnData)];
}
catch (error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
}
}
async function executeJobTemplate(inputs) {
if (inputs.resource !== 'jobTemplate' && inputs.resource !== 'job' && inputs.resource !== 'workflowJob') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid resource type '${inputs.resource}' for job template operation`);
}
try {
switch (inputs.action) {
case 'get': {
const endpoint = inputs.resource === 'workflowJob'
? `/workflow_jobs/${inputs.id}/`
: `/job_templates/${inputs.id}/`;
const response = await getAwxResources.call(this, endpoint);
const jobTemplateData = Array.isArray(response) && response.length > 0 ?
(typeof response[0] === 'string' ? JSON.parse(response[0]) : response[0]) :
response;
return [[{
json: jobTemplateData,
pairedItem: { item: 0 }
}]];
}
case 'list': {
const endpoint = inputs.resource === 'workflowJob'
? '/workflow_jobs/'
: '/job_templates/';
const templates = await getAwxResources.call(this, endpoint);
return [templates.map((t, i) => {
const itemData = typeof t === 'string'
? JSON.parse(t)
: t;
return {
json: itemData,
pairedItem: { item: i }
};
})];
}
case 'launch': {
const endpoint = `/job_templates/${inputs.id}/launch/`;
const response = await getAwxResources.call(this, endpoint);
const jobTemplateData = Array.isArray(response) && response.length > 0 ?
(typeof response[0] === 'string' ? JSON.parse(response[0]) : response[0]) :
response;
return [[{
json: jobTemplateData,
pairedItem: { item: 0 }
}]];
}
case 'setTemplate': {
const response = await getAwxResources.call(this, `/job_templates/${inputs.id}/`);
const jobTemplateData = Array.isArray(response) && response.length > 0 ?
(typeof response[0] === 'string' ? JSON.parse(response[0]) : response[0]) :
response;
return [[{
json: jobTemplateData,
pairedItem: { item: 0 }
}]];
}
case 'create': {
const response = await getAwxResources.call(this, '/job_templates/');
const jobTemplateData = Array.isArray(response) && response.length > 0 ?
(typeof response[0] === 'string' ? JSON.parse(response[0]) : response[0]) :
response;
return [[{
json: jobTemplateData,
pairedItem: { item: 0 }
}]];
}
case 'update': {
const response = await getAwxResources.call(this, `/job_templates/${inputs.id}/`);
const jobTemplateData = Array.isArray(response) && response.length > 0 ?
(typeof response[0] === 'string' ? JSON.parse(response[0]) : response[0]) :
response;
return [[{
json: jobTemplateData,
pairedItem: { item: 0 }
}]];
}
case 'delete': {
await deleteAwxResource.call(this, `/job_templates/${inputs.id}/`);
return [[{
json: { success: true },
pairedItem: { item: 0 }
}]];
}
default:
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported job template action: ${inputs.action}`);
}
}
catch (error) {
if (error instanceof Error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Job template operation failed: ${error.message}`);
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Unknown error during job template operation');
}
}
async function executeWorkflowJobTemplate(inputs) {
if (inputs.resource !== 'workflowJobTemplate') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid resource type '${inputs.resource}' for workflow job operation`);
}
const templateId = parseInt(inputs.id, 10);
const itemIndex = 0;
const hostname = this.getNodeParameter('hostname', itemIndex, '');
const credentials = await this.getCredentials('awxApi');
const { ApiClient } = require('../../src/ApiClient');
const apiClient = new ApiClient({
baseURL: hostname,
auth: {
username: credentials.username,
password: credentials.password,
},
});
const resources = new WorkflowJobTemplateResources_1.WorkflowJobTemplateResources(apiClient);
const toIDataObject = (value) => {
if (value === null || value === undefined) {
return {};
}
if (typeof value === 'object') {
if (value && 'json' in value) {
return value;
}
const result = {};
for (const [key, val] of Object.entries(value)) {
result[key] = val;
}
return result;
}
return { value };
};
const ensureIDataObject = (value) => {
return toIDataObject(value);
};
const getBoundMethod = (methodName, errorMessage) => {
const resourceRecord = resources;
const method = resourceRecord[methodName];
if (typeof method !== 'function') {
throw new Error(errorMessage);
}
return ((...args) => method(...args)).bind(resources);
};
const getNotificationMethod = (type) => {
const methodName = `getNotificationTemplates${type}`;
return getBoundMethod(methodName, `Method ${methodName} not found on WorkflowJobTemplateResources`);
};
const associateNotificationMethod = (type) => {
const methodName = `associateNotificationTemplate${type}`;
return getBoundMethod(methodName, `Method ${methodName} not found on WorkflowJobTemplateResources`);
};
const disassociateNotificationMethod = (type) => {
const methodName = `disassociateNotificationTemplate${type}`;
return getBoundMethod(methodName, `Method ${methodName} not found on WorkflowJobTemplateResources`);
};
try {
switch (inputs.action) {
case 'get': {
const workflowJobTemplate = await resources.get(templateId);
return [[{
json: ensureIDataObject(workflowJobTemplate),
pairedItem: { item: 0 }
}]];
}
case 'list': {
const workflowJobTemplates = await resources.list();
return [workflowJobTemplates.map((template, i) => ({
json: toIDataObject(template),
pairedItem: { item: i }
}))];
}
case 'create': {
const createData = {
name: inputs.name,
description: inputs.description,
organization: inputs.organizationId,
type: 'workflow_job_template',
};
const response = await resources.create(createData);
return [[{
json: toIDataObject(response),
pairedItem: { item: 0 }
}]];
}
case 'update': {
const updateData = {};
if (inputs.name !== undefined)
updateData.name = inputs.name;
if (inputs.description !== undefined)
updateData.description = inputs.description;
const response = await resources.update(templateId, updateData);
return [[{
json: toIDataObject(response),
pairedItem: { item: 0 }
}]];
}
case 'delete': {
await resources.delete(templateId);
return [[{
json: { success: true },
pairedItem: { item: 0 }
}]];
}
case 'launch': {
const launchParams = {
extra_vars: inputs.extraVars || {},
};
const response = await resources.launch(templateId, launchParams);
return [[{
json: response,
pairedItem: { item: 0 }
}]];
}
case 'associateLabel':
case 'disassociateLabel': {
const labelId = inputs.labelId;
const labelIdNum = parseInt(labelId, 10);
let response;
if (inputs.action === 'associateLabel') {
response = await resources.associateLabel(templateId, labelIdNum);
}
else {
response = await resources.disassociateLabel(templateId, labelIdNum);
}
return [[{
json: response,
pairedItem: { item: 0 }
}]];
}
case 'getSchedules': {
const schedules = await resources.getSchedules(templateId);
return [schedules.map((schedule, i) => ({
json: toIDataObject(schedule),
pairedItem: { item: i }
}))];
}
case 'createSchedule': {
const scheduleData = {
name: inputs.name,
description: inputs.description,
rrule: inputs.rrule,
};
const response = await resources.createSchedule(templateId, scheduleData);
return [[{
json: toIDataObject(response),
pairedItem: { item: 0 }
}]];
}
case 'getNotificationTemplatesError':
case 'getNotificationTemplatesStarted':
case 'getNotificationTemplatesSuccess': {
const notificationType = inputs.action.replace('getNotificationTemplates', '');
const method = getNotificationMethod(notificationType);
const notifications = await method(templateId);
return [notifications.map((notification, i) => ({
json: toIDataObject(notification),
pairedItem: { item: i }
}))];
}
case 'associateNotificationTemplateError':
case 'associateNotificationTemplateStarted':
case 'associateNotificationTemplateSuccess':
case 'disassociateNotificationTemplateError':
case 'disassociateNotificationTemplateStarted':
case 'disassociateNotificationTemplateSuccess': {
const action = inputs.action.startsWith('associate') ? 'associate' : 'disassociate';
const type = inputs.action.replace(/(associate|disassociate)NotificationTemplate/, '');
const notificationTemplateId = parseInt(inputs.notificationTemplateId, 10);
let response;
if (action === 'associate') {
const method = associateNotificationMethod(type);
response = await method(templateId, notificationTemplateId);
}
else {
const method = disassociateNotificationMethod(type);
response = await method(templateId, notificationTemplateId);
}
return [[{ json: toIDataObject(response), pairedItem: { item: 0 } }]];
}
case 'getSurveySpec': {
const surveySpec = await resources.getSurveySpec(templateId);
const surveyData = surveySpec ? { ...surveySpec } : {};
return [[{
json: toIDataObject(surveyData),
pairedItem: { item: 0 }
}]];
}
case 'createSurveySpec': {
const surveySpec = inputs.surveySpec;
const response = await resources.createSurveySpec(templateId, surveySpec);
return [[{
json: toIDataObject(response),
pairedItem: { item: 0 }
}]];
}
case 'deleteSurveySpec': {
await resources.deleteSurveySpec(templateId);
return [[{ json: { success: true }, pairedItem: { item: 0 } }]];
}
default:
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported workflow job action: ${inputs.action}`);
}
}
catch (error) {
if (error instanceof Error) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Workflow job operation failed: ${error.message}`);
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Unknown error during workflow job operation');
}
}
//# sourceMappingURL=SharedHelpers.js.map