UNPKG

@cloud-carbon-footprint/aws

Version:

The core logic to get cloud usage data and estimate energy and carbon emissions from Amazon Web Services.

164 lines 7.43 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ServiceWrapper = void 0; const client_s3_1 = require("@aws-sdk/client-s3"); const client_cloudwatch_1 = require("@aws-sdk/client-cloudwatch"); const client_cloudwatch_logs_1 = require("@aws-sdk/client-cloudwatch-logs"); const client_cost_explorer_1 = require("@aws-sdk/client-cost-explorer"); const client_athena_1 = require("@aws-sdk/client-athena"); const client_glue_1 = require("@aws-sdk/client-glue"); const csvtojson_1 = __importDefault(require("csvtojson")); const ramda_1 = require("ramda"); const stream_1 = require("stream"); const common_1 = require("@cloud-carbon-footprint/common"); class ServiceWrapper { cloudWatch; cloudWatchLogs; costExplorer; s3; athena; glue; constructor(cloudWatch, cloudWatchLogs, costExplorer, s3, athena, glue) { this.cloudWatch = cloudWatch; this.cloudWatchLogs = cloudWatchLogs; this.costExplorer = costExplorer; this.s3 = s3; this.athena = athena; this.glue = glue; } async getCostAndUsageResponse(params) { return [await this.costExplorer.send(new client_cost_explorer_1.GetCostAndUsageCommand(params))]; } async getMetricDataResponse(params) { return [await this.cloudWatch.send(new client_cloudwatch_1.GetMetricDataCommand(params))]; } async getRightsizingRecommendationResponse(params) { return [ await this.costExplorer.send(new client_cost_explorer_1.GetRightsizingRecommendationCommand(params)), ]; } async getAthenaQueryResults(queryExecutionInput) { if (!this.athena) throw new Error('Athena client not configured'); return [ await this.athena.send(new client_athena_1.GetQueryResultsCommand(queryExecutionInput)), ]; } checkForPartialData = (array) => { const isPartialData = array.some((obj) => obj.StatusCode === 'PartialData'); if (isPartialData) { throw new common_1.PartialDataError('Partial Data Returned from AWS'); } }; async getQueryByInterval(intervalInDays, func, start, end, ...args) { let startCopy = new Date(start); let endCopy = new Date(new Date(start).setDate(start.getDate() + intervalInDays)); const promiseArray = []; while (endCopy < end) { promiseArray.push(func(startCopy, endCopy, ...args)); startCopy = new Date(new Date(startCopy).setDate(start.getDate() + intervalInDays)); endCopy = new Date(new Date(startCopy).setDate(start.getDate() + intervalInDays)); } promiseArray.push(func(startCopy, end, ...args)); return Promise.all(promiseArray); } async getCloudWatchLogQueryResults(params) { return await this.cloudWatchLogs.send(new client_cloudwatch_logs_1.GetQueryResultsCommand(params)); } async describeLogGroups(params) { return await this.cloudWatchLogs.send(new client_cloudwatch_logs_1.DescribeLogGroupsCommand(params)); } async describeCloudWatchLogsQueries(params) { return await this.cloudWatchLogs.send(new client_cloudwatch_logs_1.DescribeQueriesCommand(params)); } async startCloudWatchLogsQuery(params) { return await this.cloudWatchLogs.send(new client_cloudwatch_logs_1.StartQueryCommand(params)); } async startAthenaQueryExecution(queryParams) { if (!this.athena) throw new Error('Athena client not configured'); return await this.athena.send(new client_athena_1.StartQueryExecutionCommand(queryParams)); } async getAthenaQueryExecution(queryExecutionInput) { if (!this.athena) throw new Error('Athena client not configured'); return await this.athena.send(new client_athena_1.GetQueryExecutionCommand(queryExecutionInput)); } async getAthenaQueryResultSets(queryExecutionInput) { return await this.getAthenaQueryResults(queryExecutionInput); } async getCostAndUsageResponses(params) { return await this.getCostAndUsageResponse(params); } async getMetricDataResponses(params) { const response = await this.getMetricDataResponse(params); this.checkForPartialData(response[0].MetricDataResults); return response; } async getRightsizingRecommendationsResponses(params) { return await this.getRightsizingRecommendationResponse(params); } async listBucketObjects(params) { return await this.s3.send(new client_s3_1.ListObjectsV2Command(params)); } async getComputeOptimizerRecommendationsResponse(params) { const response = await this.s3.send(new client_s3_1.GetObjectCommand(params)); if (!response.Body) { throw new Error('GetObject response has no Body'); } const nodeStream = response.Body instanceof stream_1.Readable ? response.Body : stream_1.Readable.from(response.Body); const parsedCsv = await (0, csvtojson_1.default)().fromStream(nodeStream); return JSON.parse(JSON.stringify(parsedCsv)); } async getAthenaTableDescription(params) { if (!this.glue) throw new Error('Glue client not configured'); return await this.glue.send(new client_glue_1.GetTableCommand(params)); } } exports.ServiceWrapper = ServiceWrapper; __decorate([ enablePagination('NextToken') ], ServiceWrapper.prototype, "getAthenaQueryResultSets", null); __decorate([ enablePagination('NextPageToken') ], ServiceWrapper.prototype, "getCostAndUsageResponses", null); __decorate([ enablePagination('NextToken') ], ServiceWrapper.prototype, "getMetricDataResponses", null); __decorate([ enablePagination('NextPageToken') ], ServiceWrapper.prototype, "getRightsizingRecommendationsResponses", null); function enablePagination(nextPageProperty) { return (target, propertyKey, descriptor) => { const originalMethod = descriptor.value; descriptor.value = async function (props) { const responses = []; let latestResponse; do { const args = [ { ...props, [nextPageProperty]: (0, ramda_1.path)([responses.length - 1, nextPageProperty], responses), }, ]; latestResponse = (await originalMethod.apply(this, args))[0]; responses.push(latestResponse); } while ((0, ramda_1.path)([nextPageProperty], latestResponse)); return responses; }; return descriptor; }; } //# sourceMappingURL=ServiceWrapper.js.map