Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node8, const, async #17

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
language: node_js
node_js:
- "6"
- "8"
2 changes: 1 addition & 1 deletion dryRun.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var {cleanupStacks} = require('./src');
const {cleanupStacks} = require('./src');

module.exports.test = (event, context, callback) => {
cleanupStacks(true)
Expand Down
6 changes: 3 additions & 3 deletions handler.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';

var AWS = require('aws-sdk');
var {cleanupStacks} = require('./src');
var dynamo = require('./src/dynamo.js');
const AWS = require('aws-sdk');
const {cleanupStacks} = require('./src');
const dynamo = require('./src/dynamo.js');

module.exports.cleanupStacks = (event, context, callback) => {
console.log('running some awesome logic');
Expand Down
2 changes: 1 addition & 1 deletion serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ service: nib-batman

provider:
name: aws
runtime: nodejs6.10
runtime: nodejs8.10
environment:
GITHUB_SECRET: ${env:GITHUB_SECRET}
BRANCH_KEY: slice
Expand Down
16 changes: 8 additions & 8 deletions src/dynamo.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
'use strict';

var AWS = require("aws-sdk");
var moment = require('moment');
var dynamo = new AWS.DynamoDB();
var tableName = "Batman";
const AWS = require("aws-sdk");
const moment = require('moment');
const dynamo = new AWS.DynamoDB();
const tableName = "Batman";

function putItem(deleteDate, deltedStackName) {
return new Promise((resolve, reject) => {
var params = {
const params = {
TableName: tableName,
Item: {
"StackName": {S: deltedStackName},
Expand All @@ -30,10 +30,10 @@ function putItem(deleteDate, deltedStackName) {
});
}

var writeRecords = function(deletedStackNames) {
const writeRecords = function(deletedStackNames) {
console.log('creating records...')
var nowUtcString = moment().utc().format();
var writeToDynamoPromises = deletedStackNames.map(stackName => putItem(nowUtcString, stackName));
const nowUtcString = moment().utc().format();
const writeToDynamoPromises = deletedStackNames.map(stackName => putItem(nowUtcString, stackName));
return Promise.all(writeToDynamoPromises);
}

Expand Down
129 changes: 57 additions & 72 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,57 @@
'use strict';

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

var cloudformation = new AWS.CloudFormation();
const cloudformation = new AWS.CloudFormation();

var batmanTagKey = 'Batman';
const batmanTagKey = 'Batman';

function cleanupStacks(dryRun) {
const cleanupStacks = async dryRun => {
console.log("In Clean UP Stacks");

var batmanTaggedStacks = [];

return listAllStacksWrapper()
.then(allStacks => {
console.log("allStacks", allStacks.length);
var nonMasterStacks = findNonMasterStacks(allStacks);
var oldNonMasterStacks = getOldStacks(nonMasterStacks);
var withStatuses = filterStacksByStatus(oldNonMasterStacks);
var notBatmanTag = ignoreStacksWithBatmanTag(withStatuses);
batmanTaggedStacks = getBatmanStacks(withStatuses);
return notBatmanTag;
})
.then(filteredStacks => {
console.log('filteredStacks', filteredStacks);
console.log(filteredStacks);
return deleteStacks(filteredStacks, dryRun);
})
.then(deletedStacks => {
console.log('deletedStacks', deletedStacks);
var stackNames = deletedStacks.map(stack => stack.StackName).sort();
console.log('Stack names: ', stackNames);
return {
deleted: stackNames,
mercyShown: batmanTaggedStacks.map(stack => stack.StackName).sort()
}
});
const allStacks = await listAllStacksWrapper()
console.log("allStacks", allStacks.length);
const nonMasterStacks = findNonMasterStacks(allStacks);
const oldNonMasterStacks = getOldStacks(nonMasterStacks);
const withStatuses = filterStacksByStatus(oldNonMasterStacks);
const filteredStacks = ignoreStacksWithBatmanTag(withStatuses);
const batmanTaggedStacks = getBatmanStacks(withStatuses);
console.log('filteredStacks', filteredStacks);

const deletedStacks = await deleteStacks(filteredStacks, dryRun);
console.log('deletedStacks', deletedStacks);
const stackNames = deletedStacks.map(stack => stack.StackName).sort();
console.log('Stack names: ', stackNames);
return {
deleted: stackNames,
mercyShown: batmanTaggedStacks.map(stack => stack.StackName).sort()
}
}

function deleteFromGitBranch(branchDeleteInformation) {
const deleteFromGitBranch = async (branchDeleteInformation) => {
console.log(branchDeleteInformation);
return listAllStacksWrapper()
.then(allStacks => {
var nonMasterStacks = findNonMasterStacks(allStacks);
var foundStack = stacksWithRepoAndBranchName(nonMasterStacks, branchDeleteInformation.repository.name, branchDeleteInformation.ref);
return foundStack;
})
.then(filteredStacks => {
console.log('found stack', filteredStacks);
return deleteStacks(filteredStacks);
})
.then(deletedStacks => {
console.log('deletedStacks', deletedStacks);
var stackNames = deletedStacks.map(stack => stack.StackName).sort();
console.log('Stack names: ', stackNames);
return {
deleted: stackNames,
mercyShown: []
}
});
const allStacks = await listAllStacksWrapper()
const nonMasterStacks = findNonMasterStacks(allStacks);
const foundStack = stacksWithRepoAndBranchName(nonMasterStacks, branchDeleteInformation.repository.name, branchDeleteInformation.ref);

console.log('found stack', foundStack);
const deletedStacks = await deleteStacks(foundStack);
console.log('deletedStacks', deletedStacks);
const stackNames = deletedStacks.map(stack => stack.StackName).sort();
console.log('Stack names: ', stackNames);
return {
deleted: stackNames,
mercyShown: []
}
}

function deleteStacks(stacks, dryRun) {
const deleteStacks = async (stacks, dryRun) => {
if (dryRun)
return Promise.resolve(stacks);
return stacks;

var deleteAllTheThings = stacks.map(stack => {
const deleteAllTheThings = stacks.map(stack => {
return cloudformation.deleteStack({StackName: stack.StackName}).promise();
});

Expand All @@ -78,21 +63,21 @@ function deleteStacks(stacks, dryRun) {
});
}

function listAllStacksWrapper() {
const listAllStacksWrapper = async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are not awaiting anything in this block then we can ditch the Async keyword

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was awaited in line 14, but i've removed the intermediate listAllStacksWrapper that isn't needed now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless you are awaiting within the code block you don't need the async keyword. You can still use await on line 14 since promises are awaitable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return new Promise((resolve, reject) => {
return listAllStacks(null, [], resolve, reject);
});
}

function listAllStacks(token, stackArray, resolve, reject) {
const listAllStacks = async (token, stackArray, resolve, reject) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

console.log('getting stacks.....');
var params = {NextToken: token};
const params = {NextToken: token};
cloudformation.describeStacks(params, (err, data) => {
if(err) {
console.error("ERROR: ", err);
return reject(err);
}
var stacks = stackArray.concat(data.Stacks);
const stacks = stackArray.concat(data.Stacks);
if(!data.NextToken)
return resolve(stacks);
return listAllStacks(data.NextToken, stacks, resolve, reject);
Expand All @@ -101,14 +86,14 @@ function listAllStacks(token, stackArray, resolve, reject) {

function filterStacksByStatus(stacksArray) {
return _.filter(stacksArray, stack => {
var statuses = ["CREATE_COMPLETE", "UPDATE_COMPLETE", "DELETE_FAILED"];
const statuses = ["CREATE_COMPLETE", "UPDATE_COMPLETE", "DELETE_FAILED"];
return statuses.indexOf(stack.StackStatus) >= 0;
});
}

function findNonMasterStacks(stacksArray) {
var nonMasterStacks = _.filter(stacksArray, stack => {
var branchTag = _.filter(stack.Tags, (tag) => {return tag.Key.toLowerCase() == process.env.BRANCH_KEY.toLowerCase()});
const nonMasterStacks = _.filter(stacksArray, stack => {
const branchTag = _.filter(stack.Tags, (tag) => {return tag.Key.toLowerCase() == process.env.BRANCH_KEY.toLowerCase()});
if(branchTag.length == 0) {
// check if there are any tags at all - this might be an Elastic Beanstalk app!
if (stack.Tags.length === 0) {
Expand All @@ -125,29 +110,29 @@ function isStackNonMasterElasticBeanstalk(stack) {
if (stack.StackName.toLowerCase().indexOf('master') > -1) {
return false;
}
var containsBeanstalkOutput = _.filter(stack.Outputs, ['Description', 'Beanstalk Service Role'])
const containsBeanstalkOutput = _.filter(stack.Outputs, ['Description', 'Beanstalk Service Role'])
return containsBeanstalkOutput.length > 0;
}

function getOldStacks(stacksArray) {
return _.filter(stacksArray, stack => {
var mostRecentChange = stack.LastUpdatedTime ? stack.LastUpdatedTime : stack.CreationTime;
var daysOld = moment(new Date()).diff(mostRecentChange, 'days', false);
const mostRecentChange = stack.LastUpdatedTime ? stack.LastUpdatedTime : stack.CreationTime;
const daysOld = moment(new Date()).diff(mostRecentChange, 'days', false);
return daysOld > 7;
});
}

function ignoreStacksWithBatmanTag(stacksArray) {
console.log(stacksArray)
var stacksWithoutBatmanTag = _.filter(stacksArray, stack => {
const stacksWithoutBatmanTag = _.filter(stacksArray, stack => {
return batmanTagFilter(stack.Tags).length === 0;
});
console.log(stacksWithoutBatmanTag);
return stacksWithoutBatmanTag
}

function getBatmanStacks(stacksArray) {
var stacksWithoutBatmanTag = _.filter(stacksArray, stack => {
const getBatmanStacks = stacksArray => {
const stacksWithoutBatmanTag = _.filter(stacksArray, stack => {
return batmanTagFilter(stack.Tags).length > 0;
});
return stacksWithoutBatmanTag
Expand All @@ -158,10 +143,10 @@ function batmanTagFilter(stackTags) {
}

function stacksWithRepoAndBranchName(stacksArray, repositoryName, branchName) {
var stacksWithRepoAndBranchName = _.filter(stacksArray, stack => {
var stackNameLower = stack.StackName.toLowerCase();
var repositoryNameLower = repositoryName.toLowerCase();
var branchNameLower = branchName.toLowerCase();
const stacksWithRepoAndBranchName = _.filter(stacksArray, stack => {
const stackNameLower = stack.StackName.toLowerCase();
const repositoryNameLower = repositoryName.toLowerCase();
const branchNameLower = branchName.toLowerCase();

return stackNameLower.indexOf(repositoryNameLower) > -1 && stackNameLower.indexOf(branchNameLower) > -1;
});
Expand Down
28 changes: 14 additions & 14 deletions src/index.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
var assert = require('assert');
var moment = require('moment');
var proxyquire = require('proxyquire');
var sinon = require('sinon');
const assert = require('assert');
const moment = require('moment');
const proxyquire = require('proxyquire');
const sinon = require('sinon');

var masterStackName = 'Master Tagged Stack';
const masterStackName = 'Master Tagged Stack';
process.env.BRANCH_KEY = 'Slice';

function assertDeletedStacksResponse(deletableStackNames) {
// assert our master stack isn't listed in the return set
var deletedStacks = deletableStackNames.deleted;
const deletedStacks = deletableStackNames.deleted;
assert.equal(deletedStacks.indexOf(masterStackName), -1);
assert.equal(deletedStacks.indexOf('Non Master New Stack'), -1);
assert.equal(deletedStacks.indexOf('UnTagged Stack'), -1);
Expand All @@ -25,7 +25,7 @@ function assertDeletedStacksResponse(deletableStackNames) {
describe('Cleanup', function() {
it('should remove appropriate stacks', function(done) {
deleteStacksStub.reset();
var cleanup = proxyquire("./index.js", mocks);
const cleanup = proxyquire("./index.js", mocks);
cleanup.cleanupStacks().then(deletableStackNames => {
console.log('Deleted: ', deletableStackNames.deleted);
console.log('Shown Mercy: ', deletableStackNames.mercyShown);
Expand All @@ -42,7 +42,7 @@ describe('Cleanup', function() {

it('shouldnt invoke deleteStacks when dry run true', function(done) {
deleteStacksStub.reset();
var cleanup = proxyquire("./index.js", mocks);
const cleanup = proxyquire("./index.js", mocks);
cleanup.cleanupStacks(true).then(deletableStackNames => {
console.log('Deleted: ', deletableStackNames.deleted);
console.log('Shown Mercy: ', deletableStackNames.mercyShown);
Expand All @@ -60,16 +60,16 @@ describe('Cleanup', function() {
describe('Branch delete', function() {
it('should find the stack and delete it', function(done) {
deleteStacksStub.reset();
var cleanup = proxyquire("./index.js", mocks);
var gitDeleteBranchObject = {
const cleanup = proxyquire("./index.js", mocks);
const gitDeleteBranchObject = {
ref: 'branch-name',
repository: {
name: 'repo-name'
}
};
cleanup.deleteFromGitBranch(gitDeleteBranchObject).then(deletedBranchStatus => {
// mock aws passing back a list of stacks
var deletedStacks = deletedBranchStatus.deleted;
const deletedStacks = deletedBranchStatus.deleted;
console.log('Deleted: ', deletedBranchStatus.deleted);
console.log('Shown Mercy: ', deletedBranchStatus.mercyShown);

Expand All @@ -89,14 +89,14 @@ describe('Branch delete', function() {
});
});

var promisableDeleteStack = {
const promisableDeleteStack = {
promise: function() {
return Promise.resolve({ ResponseMetadata: { RequestId: '3797470f-bb69-11e6-90e4-19b39eb619f7'}});
}
};

var deleteStacksStub = sinon.stub().returns(promisableDeleteStack);
var mocks = {
const deleteStacksStub = sinon.stub().returns(promisableDeleteStack);
const mocks = {
"aws-sdk":{
CloudFormation: function(){
this.deleteStack = deleteStacksStub;
Expand Down