From 684b48eb0c2356ba332eee6054f4d57fc48e1419 Mon Sep 17 00:00:00 2001 From: Matt Weagle Date: Wed, 18 Nov 2015 18:15:27 -0800 Subject: [PATCH] NOP 'Delete' operation during 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS' phase. --- resources/index.js | 82 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/resources/index.js b/resources/index.js index d28bed3c2..6f7230192 100644 --- a/resources/index.js +++ b/resources/index.js @@ -13,7 +13,7 @@ var SPARTA_BINARY_NAME = 'Sparta.lambda.amd64'; var SPARTA_BINARY_PATH = path.join('/tmp', SPARTA_BINARY_NAME); var MAXIMUM_RESPAWN_COUNT = 5; -var PROXIED_MODULES = ['s3', 'sns', 'apigateway'] +var PROXIED_MODULES = ['s3', 'sns', 'apigateway']; var golangProcess = null; var failCount = 0; @@ -151,31 +151,79 @@ var createForwarder = function(path) { return forwardToGolangProcess; }; +var sendResponse = function(event, context, e, results) +{ + try { + var response = require('cfn-response'); + var data = { + ERROR: e ? e.toString() : undefined, + RESULTS: results || undefined + }; + response.send(event, context, e ? response.FAILED : response.SUCCESS, data); + } + catch (eResponse) { + // NOP + console.log('ERROR sending response: ' + eResponse.toString()); + } +}; + // CustomResource Configuration exports PROXIED_MODULES.forEach(function (eachConfig) { var exportName = util.format('%sConfiguration', eachConfig); exports[exportName] = function(event, context) { try { - console.log('Delegating to configurator: ' + eachConfig); - var svc = require(util.format('./%s', eachConfig)) - svc.handler(event, context); - } catch (e) { - console.error('Failed to load configurator:' + e.toString()); + var AWS = require('aws-sdk'); + var awsConfig = new AWS.Config({}); + + // If the stack is in update mode, don't delegate + var proxyTasks = []; + proxyTasks.push(function (taskCB) { + var params = { + StackName: event.StackId + }; + var awsConfig = new AWS.Config({}); + awsConfig.logger = console; + var cloudFormation = new AWS.CloudFormation(awsConfig); + cloudFormation.describeStacks(params, taskCB); + }); - try { - var response = require('cfn-response'); - var data = { - Error: e.toString() + // Only delegate to the stack if the update is in progress. + var onStackDescription = function(e, stackDescriptionResponse) { + if (e) + { + sendResponse(event, context, e, null); + } + else { + var stackDescription = stackDescriptionResponse.Stacks ? stackDescriptionResponse.Stacks[0] : {}; + var stackStatus = stackDescription.StackStatus || ""; + if (stackStatus !== "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS") + { + try { + console.log('Delegating to configurator: ' + eachConfig); + var svc = require(util.format('./%s', eachConfig)); + svc.handler(event, context); + } catch (e) { + sendResponse(event, context, e, null); + } + } else { + console.log('Bypassing configurator execution due to status: ' + stackStatus); + sendResponse(event, context, e, "NOP"); + } } - response.send(event, context, response.FAILED, data); - } - catch (loader) { - // NOP - } + }; + // Get the current stack status + var params = { + StackName: event.StackId + }; + var cloudFormation = new AWS.CloudFormation(awsConfig); + cloudFormation.describeStacks(params, onStackDescription); + } catch (e) { + console.error('Failed to load configurator:' + e.toString()); + sendResponse(event, context, e, null); } - } -}) + }; +}); exports.main = createForwarder('/'); // Additional golang handlers to be dynamically appended below