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

configurable branch key (allow regex, multiple matches), centralised … #16

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
11 changes: 11 additions & 0 deletions config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
var batmanTagKey = 'Batman';
var stackToKeepRegexes = [/^test$/i, /^master$/i, /^test-master$/i]
var branchKey = 'stage'
var branchKeyMatches = (key) => key.toLowerCase() === branchKey.toLowerCase()

module.exports = {
batmanTagKey,
stackToKeepRegexes,
branchKey,
branchKeyMatches
};
3 changes: 1 addition & 2 deletions serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ provider:
runtime: nodejs6.10
environment:
GITHUB_SECRET: ${env:GITHUB_SECRET}
BRANCH_KEY: slice


region: ap-southeast-2
iamRoleStatements:
- Effect: "Allow"
Expand Down
29 changes: 17 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
var AWS = require('aws-sdk');
var _ = require('lodash');
var moment = require('moment');

var config = require('../config')
var cloudformation = new AWS.CloudFormation();

var batmanTagKey = 'Batman';
var batmanTagKey = config.batmanTagKey
var stackToKeepRegexes = config.stackToKeepRegexes
var branchKeyMatches = config.branchKeyMatches

function cleanupStacks(dryRun) {
console.log("In Clean UP Stacks");
Expand All @@ -16,8 +18,8 @@ function cleanupStacks(dryRun) {
return listAllStacksWrapper()
.then(allStacks => {
console.log("allStacks", allStacks.length);
var nonMasterStacks = findNonMasterStacks(allStacks);
var oldNonMasterStacks = getOldStacks(nonMasterStacks);
var stacksOnUnprotectedBranch = getBranchesAllowedToRemove(allStacks, stackToKeepRegexes, branchKeyMatches);
var oldNonMasterStacks = getOldStacks(stacksOnUnprotectedBranch);
var withStatuses = filterStacksByStatus(oldNonMasterStacks);
var notBatmanTag = ignoreStacksWithBatmanTag(withStatuses);
batmanTaggedStacks = getBatmanStacks(withStatuses);
Expand All @@ -29,7 +31,7 @@ function cleanupStacks(dryRun) {
return deleteStacks(filteredStacks, dryRun);
})
.then(deletedStacks => {
console.log('deletedStacks', deletedStacks);
console.log('deletedStacks', JSON.stringify(deletedStacks, null, 2));
var stackNames = deletedStacks.map(stack => stack.StackName).sort();
console.log('Stack names: ', stackNames);
return {
Expand All @@ -43,8 +45,8 @@ function deleteFromGitBranch(branchDeleteInformation) {
console.log(branchDeleteInformation);
return listAllStacksWrapper()
.then(allStacks => {
var nonMasterStacks = findNonMasterStacks(allStacks);
var foundStack = stacksWithRepoAndBranchName(nonMasterStacks, branchDeleteInformation.repository.name, branchDeleteInformation.ref);
var stacksOnUnprotectedBranch = getBranchesAllowedToRemove(allStacks, stackToKeepRegexes, branchKeyMatches);
var foundStack = stacksWithRepoAndBranchName(stacksOnUnprotectedBranch, branchDeleteInformation.repository.name, branchDeleteInformation.ref);
return foundStack;
})
.then(filteredStacks => {
Expand Down Expand Up @@ -106,19 +108,22 @@ function filterStacksByStatus(stacksArray) {
});
}

function findNonMasterStacks(stacksArray) {
var nonMasterStacks = _.filter(stacksArray, stack => {
var branchTag = _.filter(stack.Tags, (tag) => {return tag.Key.toLowerCase() == process.env.BRANCH_KEY.toLowerCase()});
function getBranchesAllowedToRemove(stacksArray, arrayOfRegexes, branchKeyMatches) {
var nonMatchingStacks = _.filter(stacksArray, stack => {
var branchTag = _.filter(stack.Tags, tag => branchKeyMatches(tag.Key));
if(branchTag.length == 0) {
// check if there are any tags at all - this might be an Elastic Beanstalk app!
if (stack.Tags.length === 0) {
console.log('stack without tag: ', stack.StackName)
return isStackNonMasterElasticBeanstalk(stack);
}
return false;
}
return branchTag[0].Value.toLowerCase() != 'master';
const branchTagValue = branchTag[0].Value.toLowerCase()
const branchValueIsProtected = arrayOfRegexes.some(r => r.test(branchTagValue))
return !branchValueIsProtected
});
return nonMasterStacks;
return nonMatchingStacks;
}

function isStackNonMasterElasticBeanstalk(stack) {
Expand Down
17 changes: 8 additions & 9 deletions src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ var assert = require('assert');
var moment = require('moment');
var proxyquire = require('proxyquire');
var sinon = require('sinon');
var config = require('../config')

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

function assertDeletedStacksResponse(deletableStackNames) {
// assert our master stack isn't listed in the return set
Expand All @@ -21,7 +21,6 @@ function assertDeletedStacksResponse(deletableStackNames) {
assert.equal(deletedStacks.length, 3);
}


describe('Cleanup', function() {
it('should remove appropriate stacks', function(done) {
deleteStacksStub.reset();
Expand Down Expand Up @@ -106,7 +105,7 @@ var mocks = {
StackName: 'Master Tagged Stack',
StackStatus: 'CREATE_COMPLETE',
Tags: [{
Key: 'Slice',
Key: config.branchKey,
Value: 'Master'
}],
Outputs: [],
Expand All @@ -121,7 +120,7 @@ var mocks = {
StackName: 'Non Master New Stack',
StackStatus: 'CREATE_COMPLETE',
Tags: [{
Key: 'Slice',
Key: config.branchKey,
Value: 'non master'
}],
Outputs: [],
Expand All @@ -130,7 +129,7 @@ var mocks = {
StackName: 'Delete Me',
StackStatus: 'CREATE_COMPLETE',
Tags: [{
Key: 'Slice',
Key: config.branchKey,
Value: 'non master'
}],
Outputs: [],
Expand All @@ -139,7 +138,7 @@ var mocks = {
StackName: 'Try deleting failed again',
StackStatus: 'DELETE_FAILED',
Tags: [{
Key: 'Slice',
Key: config.branchKey,
Value: 'non master'
}],
Outputs: [],
Expand All @@ -148,7 +147,7 @@ var mocks = {
StackName: 'Do not delete me',
StackStatus: 'UPDATE_IN_PROGRESS',
Tags: [{
Key: 'Slice',
Key: config.branchKey,
Value: 'non master'
}],
Outputs: [],
Expand All @@ -157,7 +156,7 @@ var mocks = {
StackName: 'Tagged Batman Not Deleted',
StackStatus: 'CREATE_COMPLETE',
Tags: [{
Key: 'Slice',
Key: config.branchKey,
Value: 'non master'
},{
Key: 'Batman',
Expand All @@ -169,7 +168,7 @@ var mocks = {
StackName: 'branch-name-repo-name',
StackStatus: 'CREATE_COMPLETE',
Tags: [{
Key: 'Slice',
Key: config.branchKey,
Value: 'non master'
},{
Key: 'Batman',
Expand Down