n8n-nodes-aws-cost-explorer
Version:
N8N node for AWS Cost Explorer to retrieve cost and usage data
360 lines (359 loc) • 14.6 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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AwsCostExplorer = void 0;
const n8n_workflow_1 = require("n8n-workflow");
class AwsCostExplorer {
constructor() {
this.description = {
displayName: 'AWS Cost Explorer',
name: 'awsCostExplorer',
icon: 'file:awscostexplorer.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Get cost and usage data from AWS Cost Explorer',
defaults: {
name: 'AWS Cost Explorer',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'awsCostExplorerApi',
required: true,
},
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Cost and Usage',
value: 'costAndUsage',
},
{
name: 'Dimension Values',
value: 'dimensionValues',
},
{
name: 'Total Cost',
value: 'totalCost',
},
],
default: 'costAndUsage',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: [
'costAndUsage',
],
},
},
options: [
{
name: 'Get',
value: 'get',
description: 'Get cost and usage data',
action: 'Get cost and usage data',
},
],
default: 'get',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: [
'dimensionValues',
],
},
},
options: [
{
name: 'Get',
value: 'get',
description: 'Get dimension values',
action: 'Get dimension values',
},
],
default: 'get',
},
{
displayName: 'Start Date',
name: 'startDate',
type: 'string',
displayOptions: {
show: {
resource: ['costAndUsage', 'dimensionValues'],
operation: ['get'],
},
},
default: '',
placeholder: '2023-01-01',
description: 'Start date in YYYY-MM-DD format',
required: true,
},
{
displayName: 'End Date',
name: 'endDate',
type: 'string',
displayOptions: {
show: {
resource: ['costAndUsage', 'dimensionValues'],
operation: ['get'],
},
},
default: '',
placeholder: '2023-01-31',
description: 'End date in YYYY-MM-DD format',
required: true,
},
{
displayName: 'Granularity',
name: 'granularity',
type: 'options',
displayOptions: {
show: {
resource: ['costAndUsage'],
operation: ['get'],
},
},
options: [
{
name: 'Daily',
value: 'DAILY',
},
{
name: 'Monthly',
value: 'MONTHLY',
},
{
name: 'Hourly',
value: 'HOURLY',
},
],
default: 'MONTHLY',
},
{
displayName: 'Metrics',
name: 'metrics',
type: 'multiOptions',
displayOptions: {
show: {
resource: ['costAndUsage'],
operation: ['get'],
},
},
options: [
{
name: 'Blended Cost',
value: 'BlendedCost',
},
{
name: 'Unblended Cost',
value: 'UnblendedCost',
},
{
name: 'Usage Quantity',
value: 'UsageQuantity',
},
],
default: ['UnblendedCost'],
},
{
displayName: 'Service Filter',
name: 'serviceFilter',
type: 'string',
displayOptions: {
show: {
resource: ['costAndUsage'],
operation: ['get'],
},
},
default: '',
placeholder: 'MongoDB Atlas (pay-as-you-go)',
description: 'Filter by specific service name (optional)',
},
{
displayName: 'Group By Service',
name: 'groupByService',
type: 'boolean',
displayOptions: {
show: {
resource: ['costAndUsage'],
operation: ['get'],
},
},
default: true,
description: 'Group results by service name',
},
{
displayName: 'Dimension',
name: 'dimension',
type: 'options',
displayOptions: {
show: {
resource: ['dimensionValues'],
operation: ['get'],
},
},
options: [
{
name: 'Service',
value: 'SERVICE',
},
{
name: 'Linked Account',
value: 'LINKED_ACCOUNT',
},
{
name: 'Instance Type',
value: 'INSTANCE_TYPE',
},
{
name: 'Region',
value: 'REGION',
},
],
default: 'SERVICE',
required: true,
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
const length = items.length;
const credentials = await this.getCredentials('awsCostExplorerApi');
// Dynamic import to avoid build-time issues
const { CostExplorerClient, GetCostAndUsageCommand, GetDimensionValuesCommand } = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-cost-explorer')));
const client = new CostExplorerClient({
region: credentials.region,
credentials: {
accessKeyId: credentials.accessKeyId,
secretAccessKey: credentials.secretAccessKey,
},
});
for (let i = 0; i < length; i++) {
try {
const resource = this.getNodeParameter('resource', i);
const operation = this.getNodeParameter('operation', i);
if (resource === 'costAndUsage') {
if (operation === 'get') {
const startDate = this.getNodeParameter('startDate', i);
const endDate = this.getNodeParameter('endDate', i);
const granularity = this.getNodeParameter('granularity', i);
const metrics = this.getNodeParameter('metrics', i);
const serviceFilter = this.getNodeParameter('serviceFilter', i);
const groupByService = this.getNodeParameter('groupByService', i);
const commandParams = {
TimePeriod: {
Start: startDate,
End: endDate,
},
Granularity: granularity,
Metrics: metrics,
};
if (groupByService) {
commandParams.GroupBy = [
{
Type: 'DIMENSION',
Key: 'SERVICE',
},
];
}
if (serviceFilter && serviceFilter.trim()) {
commandParams.Filter = {
Dimensions: {
Key: 'SERVICE',
Values: [serviceFilter],
},
};
}
const command = new GetCostAndUsageCommand(commandParams);
const response = await client.send(command);
returnData.push(response);
}
}
if (resource === 'dimensionValues') {
if (operation === 'get') {
const dimension = this.getNodeParameter('dimension', i);
const startDate = this.getNodeParameter('startDate', i, '');
const endDate = this.getNodeParameter('endDate', i, '');
const command = new GetDimensionValuesCommand({
TimePeriod: {
Start: startDate || '2023-01-01',
End: endDate || '2023-12-31',
},
Dimension: dimension,
});
const response = await client.send(command);
returnData.push(response);
}
}
if (resource === 'totalCost') {
if (operation === 'get') {
const startDate = this.getNodeParameter('startDate', i);
const endDate = this.getNodeParameter('endDate', i);
const granularity = this.getNodeParameter('granularity', i);
const metrics = this.getNodeParameter('metrics', i);
const command = new GetCostAndUsageCommand({
TimePeriod: {
Start: startDate,
End: endDate,
},
Granularity: granularity,
Metrics: metrics,
});
const response = await client.send(command);
returnData.push(response);
}
}
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({ error: error.message });
continue;
}
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}
exports.AwsCostExplorer = AwsCostExplorer;