Skip to content

Commit

Permalink
[INF-2535] Remove unnecessary dependencies. (#38)
Browse files Browse the repository at this point in the history
* [INF-2535] Remove unnecessary dependencies.

* 0.3.1
  • Loading branch information
ohookins authored Nov 22, 2023
1 parent a3e844d commit ee3a4ba
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 110 deletions.
104 changes: 51 additions & 53 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

const _ = require('lodash');
const async = require('async');
const util = require('util');
const { ECS } = require("@aws-sdk/client-ecs");
const combiner = require('stream-combiner');
const FormatStream = require('./lib/format-transform-stream');
Expand All @@ -23,43 +22,40 @@ module.exports = function (options, cb) {
charset: 'alphabetic'
});

async.waterfall([
function (next) {
const ecs = new ECS({ region: region });
ecs.describeTaskDefinition({ taskDefinition: options.taskDefinitionArn }, function (err, result) {
if (err) return next(err);

if (!result.taskDefinition || !result.taskDefinition.taskDefinitionArn) {
return next(new Error(`Could not find taskDefinition with the arn "${options.taskDefinitionArn}"`));
}
const ecs = new ECS({ region: region });
ecs.describeTaskDefinition({ taskDefinition: options.taskDefinitionArn })
.then((result) => {
if (!result.taskDefinition || !result.taskDefinition.taskDefinitionArn) {
throw new Error(`Could not find taskDefinition with the arn "${options.taskDefinitionArn}"`);
}

containerDefinition = _.find(result.taskDefinition.containerDefinitions, { 'name': options.containerName });
containerDefinition = result.taskDefinition.containerDefinitions.find((def) => {
return def.name === options.containerName;
});

if (!containerDefinition) {
return next(new Error(`Could not find container by the name "${options.containerName}" in task definition`));
}
if (!containerDefinition) {
throw new Error(`Could not find container by the name "${options.containerName}" in task definition`);
}

loggingDriver = containerDefinition['logConfiguration']['logDriver'];
if (loggingDriver != 'awslogs') {
return next(new Error('Logging dirver is awslogs. Can not stream logs unless logging driver is awslogs'));
}
loggingDriver = containerDefinition['logConfiguration']['logDriver'];
if (loggingDriver != 'awslogs') {
throw new Error('Logging dirver is awslogs. Can not stream logs unless logging driver is awslogs');
}

if (result.taskDefinition.networkMode === 'awsvpc') {
if (options.subnets === undefined || options.securityGroups === undefined) {
return next(new Error('Task definition networkMode is awsvpc, this requires you to specify subnets and security-groups.'));
}
if (result.taskDefinition.networkMode === 'awsvpc') {
if (options.subnets === undefined || options.securityGroups === undefined) {
throw new Error('Task definition networkMode is awsvpc, this requires you to specify subnets and security-groups.');
}
else {
if (options.subnets !== undefined || options.securityGroups !== undefined || options.assignPublicIp) {
return next(new Error('Network options are only allowed when task definition networkMode is awsvpc. You should not specify subnets, security-groups or assign-public-ip'));
}
}
else {
if (options.subnets !== undefined || options.securityGroups !== undefined || options.assignPublicIp) {
throw new Error('Network options are only allowed when task definition networkMode is awsvpc. You should not specify subnets, security-groups or assign-public-ip');
}
}

logOptions = containerDefinition['logConfiguration']['options'];
next();
});
},
function (next) {
logOptions = containerDefinition['logConfiguration']['options'];
})
.then(() => {
const params = {
clusterArn: options.clusterArn,
cmd: options.cmd,
Expand All @@ -72,28 +68,30 @@ module.exports = function (options, cb) {
assignPublicIp: options.assignPublicIp,
subnets: options.subnets,
securityGroups: options.securityGroups
}

taskRunner.run(params, next);
}
], function (err, taskDefinition) {
if (err) return cb(err);
};

taskRunner.runPromisified = util.promisify(taskRunner.run);
return taskRunner.runPromisified(params);
})
.then((taskDefinition) => {
const taskArn = taskDefinition.tasks[0].taskArn;
const taskId = taskArn.substring(taskArn.lastIndexOf('/') + 1);
const formatter = new FormatStream();

const logs = new LogStream({
logGroup: logOptions['awslogs-group'],
logStream: `${logOptions['awslogs-stream-prefix']}/${options.containerName}/${taskId}`,
endOfStreamIdentifier: endOfStreamIdentifier
});

const taskArn = taskDefinition.tasks[0].taskArn;
const taskId = taskArn.substring(taskArn.lastIndexOf('/') + 1);
const formatter = new FormatStream();
const stream = combiner(logs, formatter);
stream.logStream = logs;
stream.taskRunner = taskRunner;
stream.taskId = taskId;

const logs = new LogStream({
logGroup: logOptions['awslogs-group'],
logStream: `${logOptions['awslogs-stream-prefix']}/${options.containerName}/${taskId}`,
endOfStreamIdentifier: endOfStreamIdentifier
cb(null, stream);
})
.catch((err) => {
cb(err);
});

const stream = combiner(logs, formatter);
stream.logStream = logs;
stream.taskRunner = taskRunner;
stream.taskId = taskId;

cb(null, stream);
});
}
21 changes: 4 additions & 17 deletions lib/log-stream.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
'use strict'

const _ = require('lodash');
const { CloudWatchLogs } = require("@aws-sdk/client-cloudwatch-logs");
const moment = require('moment');
const Readable = require('stream').Readable;

const region = process.env.AWS_DEFAULT_REGION || 'us-east-1';

// Take cloudwatchlogs.getLogEvents data and
// return logs events as strings
function renderLogEvents(data) {
const lines = _.map(data.events, function (event) {
return moment(event.timestamp).format('Y-MM-DD H:m:ss ZZ').cyan + ' ' + event.message;
});

return lines.join("\n");
}

class LogStream extends Readable {
constructor(options) {
options.objectMode = true;
super(options);

this.options = _.defaults(options, {
durationBetweenPolls: 1000,
timeoutBeforeFirstLogs: 300 * 1000
});
this.options = options;
this.options.durationBetweenPolls = options.durationBetweenPolls || 1000;
this.options.timeoutBeforeFirstLogs = options.timeoutBeforeFirstLogs || 300 * 1000;

this.eventBuffer = [];
this.pending = false;
Expand Down Expand Up @@ -68,7 +55,7 @@ class LogStream extends Readable {
// version of eof identifiter so that listener doesn't accidentally
// catch the eof identifier if container echoes out running command.
const endOfStreamIdentifierBase64 = Buffer.from(this.options.endOfStreamIdentifier).toString('base64');
const endEvent = _.find(data.events, (event) => event.message.includes(endOfStreamIdentifierBase64));
const endEvent = data.events.find((event) => event.message.includes(endOfStreamIdentifierBase64));

if (this.stopRequested) {
this.exitCode = 130;
Expand Down
45 changes: 9 additions & 36 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bugcrowd/ecs-task-runner",
"version": "0.3.0",
"version": "0.3.1",
"description": "Run a task on ecs and stream logs from Cloudwatch Logs to the console",
"main": "index.js",
"engines": {
Expand All @@ -27,9 +27,6 @@
"dependencies": {
"@aws-sdk/client-cloudwatch-logs": "^3.451.0",
"@aws-sdk/client-ecs": "^3.451.0",
"async": "^2.6.1",
"lodash": "^4.17.11",
"moment": "^2.22.2",
"randomstring": "^1.1.5",
"stream-combiner": "^0.2.2",
"yargs": "^17.7.1"
Expand Down

0 comments on commit ee3a4ba

Please sign in to comment.