Skip to content

Commit

Permalink
[INF-2535] Update to use AWS SDK v3 (#36)
Browse files Browse the repository at this point in the history
* [INF-2535] Update to use AWS SDK v3

* Migrate tests for service.js

* Refactor remaining tests.

* 0.3.0
  • Loading branch information
ohookins committed Nov 27, 2023
1 parent 2c1baa8 commit 6f3c302
Show file tree
Hide file tree
Showing 32 changed files with 5,037 additions and 879 deletions.
4 changes: 2 additions & 2 deletions bin/ecs-deployment-monitor
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

const monitor = require('../');

var argv = require('yargs')
const argv = require('yargs')
.demand(['cluster', 'service-name', 'task-definition'])
.default('failure-threshold', '.25')
.argv;

var deployment = monitor({
const deployment = monitor({
serviceName: argv.serviceName,
clusterArn: argv.cluster,
taskDefinitionArn: argv.taskDefinition,
Expand Down
10 changes: 1 addition & 9 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
'use strict'

const AWS = require('aws-sdk');
const _ = require('lodash');

const Service = require('./lib/service');
const Deployment = require('./lib/deployment');
const Renderer = require('./lib/renderer');

module.exports = function(options) {
module.exports = function (options) {
_.defaults(options, {
continueService: false
});

// Set the default region to 'us-east-1' if not already set
if (!AWS.config.region) {
AWS.config.update({
region: process.env.AWS_DEFAULT_REGION || 'us-east-1'
});
}

let service = new Service({
serviceName: options.serviceName,
clusterArn: options.clusterArn
Expand Down
15 changes: 7 additions & 8 deletions lib/deployment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict'

const AWS = require('aws-sdk');
const EventEmitter = require('events');
const async = require('async');
const _ = require('lodash');
Expand Down Expand Up @@ -52,14 +51,14 @@ class Deployment extends EventEmitter {
this.notFoundCount++;
return;
}

this.setState('NotFound');
}

this.stoppedTasks((err, tasks) => {
if (err) return this.emit('error', err);
var taskArns = _.map(tasks, (task) => task.taskArn);
logger.log({level: 'debug', type: 'deployment', message: `Tasks Stopped: ${taskArns.join(', ')}` });
logger.log({ level: 'debug', type: 'deployment', message: `Tasks Stopped: ${taskArns.join(', ')}` });

this.tasksFailed = _.map(tasks, (task) => task.taskArn);
this.tasksFailedFull = tasks;
Expand All @@ -78,7 +77,7 @@ class Deployment extends EventEmitter {
let deploymentTasks = filterDeploymentTasks(event.tasks);
let deploymentTasksArns = _.map(deploymentTasks, (task) => task.taskArn);
this.tasksStarted.push.apply(this.tasksStarted, deploymentTasksArns);
logger.log({level: 'debug', type: 'deployment', message: `Tasks Started: ${deploymentTasksArns.join(', ')}` });
logger.log({ level: 'debug', type: 'deployment', message: `Tasks Started: ${deploymentTasksArns.join(', ')}` });
}

if (event instanceof events.SteadyEvent) {
Expand Down Expand Up @@ -113,7 +112,7 @@ class Deployment extends EventEmitter {
* @return {array}
*/
evaluate(evaluators, cb) {
logger.log({level: 'info', type: 'deployment', message: 'Starting deployment evaluation' });
logger.log({ level: 'info', type: 'deployment', message: 'Starting deployment evaluation' });

// Skip evaluation if service is not initiated or has failed
if (!this.service.initiated || this.isFailure()) return cb();
Expand Down Expand Up @@ -172,15 +171,15 @@ class Deployment extends EventEmitter {
* @return {boolean}
*/
setState(state) {
logger.log({level: 'info', type: 'deployment', message: `Setting deployment state to "${state}"` });
logger.log({ level: 'info', type: 'deployment', message: `Setting deployment state to "${state}"` });

this.state = state;
this.history.push({ state: this.state, transitionedAt: Date.now()});
this.history.push({ state: this.state, transitionedAt: Date.now() });
this.emit('state', state);
this.emit(`state:${state}`);

if (this.isSteady() || this.isFailure()) {
logger.log({level: 'info', type: 'deployment', message: `Deployment has ended` });
logger.log({ level: 'info', type: 'deployment', message: `Deployment has ended` });

this.end = true;
this.destroy();
Expand Down
4 changes: 1 addition & 3 deletions lib/evaluators/draining.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
'use strict'

const AWS = require('aws-sdk');
'use strict';
const _ = require('lodash');

module.exports = function(deployment, cb) {
Expand Down
4 changes: 1 addition & 3 deletions lib/evaluators/live.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
'use strict'

const AWS = require('aws-sdk');
'use strict';
const _ = require('lodash');

module.exports = function(deployment, cb) {
Expand Down
5 changes: 1 addition & 4 deletions lib/evaluators/steady.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
'use strict'

const AWS = require('aws-sdk');

'use strict';
module.exports = function(deployment, cb) {
cb(null, deployment.steady);
}
4 changes: 1 addition & 3 deletions lib/events/steady-event.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use static'

'use static';
const Event = require('./event');
const AWS = require('aws-sdk');

class SteadyEvent extends Event {
static test(rawEvent) {
Expand Down
4 changes: 1 addition & 3 deletions lib/events/tasks-started-event.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use static'

'use static';
const Event = require('./event');
const AWS = require('aws-sdk');

class TasksStartedEvent extends Event {
extractableTypes() {
Expand Down
4 changes: 1 addition & 3 deletions lib/events/tasks-stopped-event.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use static'

'use static';
const Event = require('./event');
const AWS = require('aws-sdk');

class TasksStoppedEvent extends Event {
extractableTypes() {
Expand Down
19 changes: 9 additions & 10 deletions lib/resources/tasks.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
'use strict'

const AWS = require('aws-sdk');
const { ECS } = require("@aws-sdk/client-ecs");

module.exports = function(service, tasks, cb) {
var params = {
module.exports = function (service, tasks, cb) {
const params = {
cluster: service.options.clusterArn,
tasks: tasks
};
const region = process.env.AWS_DEFAULT_REGION || 'us-east-1';
const ecs = new ECS({ region: region });

var ecs = new AWS.ECS();

ecs.describeTasks(params, (err, data) => {
if (err) return cb(err);
cb(null, data['tasks']);
});
}
ecs.describeTasks(params)
.then(data => cb(null, data['tasks']))
.catch(err => cb(err));
};
51 changes: 24 additions & 27 deletions lib/service.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const AWS = require('aws-sdk');
const { ECS } = require("@aws-sdk/client-ecs");
const { ElasticLoadBalancingV2: ELBv2 } = require("@aws-sdk/client-elastic-load-balancing-v2");
const EventEmitter = require('events');
const _ = require('lodash');

Expand All @@ -19,6 +20,9 @@ class Service extends EventEmitter {
this.initiated = false;
this.stop = false;
this.launchType = 'EC2';
this.region = process.env.AWS_DEFAULT_REGION || 'us-east-1';
this.ecs = new ECS({ region: this.region });
this.alb = new ELBv2({ region: this.region });

this.options = _.defaults(options, {
durationBetweenPolls: 3000,
Expand All @@ -34,14 +38,12 @@ class Service extends EventEmitter {
* Fetch service details from AWS
*/
async _service() {
const ecs = new AWS.ECS();

const params = {
services: [this.options.serviceName],
cluster: this.options.clusterArn,
};

const data = await ecs.describeServices(params).promise();
const data = await this.ecs.describeServices(params);
logger.info(`Retrieved service data for ${data.services[0].serviceArn}`);
return data.services[0];
}
Expand All @@ -50,11 +52,10 @@ class Service extends EventEmitter {
* Fetch health for all targets
*/
async _targets() {
const alb = new AWS.ELBv2();
const lbs = this.raw.loadBalancers.filter((lb) => !!lb.targetGroupArn);

const results = await Promise.all(lbs.map(async (lb) => {
const data = await alb.describeTargetHealth({TargetGroupArn: lb.targetGroupArn}).promise();
const data = await this.alb.describeTargetHealth({ TargetGroupArn: lb.targetGroupArn });
return data.TargetHealthDescriptions;
}));

Expand All @@ -65,16 +66,14 @@ class Service extends EventEmitter {
* Fetch Cluster Container Instances
*/
async _clusterContainerInstances() {
const ecs = new AWS.ECS();

const {containerInstanceArns} = await ecs.listContainerInstances({
const { containerInstanceArns } = await this.ecs.listContainerInstances({
cluster: this.options.clusterArn,
}).promise();
});

const {containerInstances}= await ecs.describeContainerInstances({
const { containerInstances } = await this.ecs.describeContainerInstances({
cluster: this.options.clusterArn,
containerInstances: containerInstanceArns,
}).promise();
});

return containerInstances;
}
Expand All @@ -87,22 +86,20 @@ class Service extends EventEmitter {
* one hour after stopping.
*/
async _tasks() {
const ecs = new AWS.ECS();

const {taskArns} = await ecs.listTasks({
const { taskArns } = await this.ecs.listTasks({
cluster: this.options.clusterArn,
serviceName: this.options.serviceName,
}).promise();
});

// Skip describeTasks if no tasks are in this service
if (taskArns.length === 0) {
return [];
}

const {tasks} = await ecs.describeTasks({
const { tasks } = await this.ecs.describeTasks({
cluster: this.options.clusterArn,
tasks: taskArns,
}).promise();
});

return tasks;
}
Expand All @@ -128,7 +125,7 @@ class Service extends EventEmitter {
* were emited. Called on service 'updated' event.
*/
_emitNewEvents() {
logger.log({level: 'info', type: 'service', message: 'Emitting new service events'});
logger.log({ level: 'info', type: 'service', message: 'Emitting new service events' });

if (!this.primaryDeployment) return;

Expand All @@ -137,9 +134,9 @@ class Service extends EventEmitter {
}

const events = _(this.raw.events)
.filter((event) => event.createdAt > this.eventsAfter)
.sortBy('createdAt')
.value();
.filter((event) => event.createdAt > this.eventsAfter)
.sortBy('createdAt')
.value();

if (events.length > 0) this.eventsAfter = _.last(events).createdAt;

Expand All @@ -151,7 +148,7 @@ class Service extends EventEmitter {
];

for (const event of events) {
logger.log({level: 'debug', type: 'service-event', message: JSON.stringify(event)});
logger.log({ level: 'debug', type: 'service-event', message: JSON.stringify(event) });
const eventClass = eventClassTestOrder.find((type) => type.test(event));
eventClass.convert(this, event, (error, value) => {
if (error) return this.emit('error', error);
Expand Down Expand Up @@ -228,7 +225,7 @@ class Service extends EventEmitter {
* Update service, target health and cluster instance details
*/
async update() {
logger.log({level: 'info', type: 'service', message: 'Service update initiated'});
logger.log({ level: 'info', type: 'service', message: 'Service update initiated' });

try {
this.raw = await this._service();
Expand All @@ -254,7 +251,7 @@ class Service extends EventEmitter {
if (this.end) return;

this.initiated = true;
logger.log({level: 'info', type: 'service', message: 'Service update completed'});
logger.log({ level: 'info', type: 'service', message: 'Service update completed' });
this.emit('updated');
}

Expand All @@ -266,7 +263,7 @@ class Service extends EventEmitter {
*/
getContainerInstance(containerInstanceArn) {
return this.clusterContainerInstances.find((ci) =>
ci.containerInstanceArn === containerInstanceArn );
ci.containerInstanceArn === containerInstanceArn);
}

/**
Expand Down Expand Up @@ -352,7 +349,7 @@ class Service extends EventEmitter {
* Prevents future polling of AWS for service updates
*/
destroy() {
logger.log({level: 'info', type: 'service', message: 'Destroying Service'});
logger.log({ level: 'info', type: 'service', message: 'Destroying Service' });
this.end = true;
clearTimeout(this.pollInterval);
}
Expand Down
Loading

0 comments on commit 6f3c302

Please sign in to comment.