-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Transform SNS elements and move them to the alias stack.
- Loading branch information
Frank Schmid
committed
May 29, 2017
1 parent
36e8259
commit 9e2728f
Showing
2 changed files
with
83 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
'use strict'; | ||
|
||
/** | ||
* Handle SNS Lambda subscriptions. | ||
*/ | ||
|
||
const _ = require('lodash'); | ||
const BbPromise = require('bluebird'); | ||
const utils = require('../utils'); | ||
|
||
module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStackTemplate) { | ||
const stageStack = this._serverless.service.provider.compiledCloudFormationTemplate; | ||
const aliasStack = this._serverless.service.provider.compiledCloudFormationAliasTemplate; | ||
|
||
this.options.verbose && this._serverless.cli.log('Processing SNS Lambda subscriptions'); | ||
|
||
const aliasResources = []; | ||
|
||
const aliases = _.assign({}, _.pickBy(aliasStack.Resources, [ 'Type', 'AWS::Lambda::Alias' ])); | ||
const versions = _.assign({}, _.pickBy(aliasStack.Resources, [ 'Type', 'AWS::Lambda::Version' ])); | ||
|
||
// Add alias name to topics to disambiguate behavior | ||
const snsTopics = | ||
_.assign({}, | ||
_.pickBy(stageStack.Resources, [ 'Type', 'AWS::SNS::Topic' ])); | ||
|
||
_.forOwn(snsTopics, (topic, name) => { | ||
topic.DependsOn = topic.DependsOn || []; | ||
// Remap lambda subscriptions | ||
const lambdaSubscriptions = _.pickBy(topic.Properties.Subscription, ['Protocol', 'lambda']); | ||
_.forOwn(lambdaSubscriptions, subscription => { | ||
const functionNameRef = utils.findAllReferences(_.get(subscription, 'Endpoint')); | ||
const functionName = _.replace(_.get(functionNameRef, '[0].ref', ''), /LambdaFunction$/, ''); | ||
const versionName = _.find(_.keys(versions), version => _.startsWith(version, functionName)); | ||
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName)); | ||
|
||
subscription.Endpoint = { Ref: aliasName }; | ||
|
||
// Add dependency on function version | ||
topic.DependsOn.push(versionName); | ||
topic.DependsOn.push(aliasName); | ||
}); | ||
|
||
topic.Properties.TopicName = `${topic.Properties.TopicName}-${this._alias}`; | ||
|
||
delete stageStack.Resources[name]; | ||
}); | ||
|
||
// Fetch lambda permissions. These have to be updated later to allow the aliased functions. | ||
const snsLambdaPermissions = | ||
_.assign({}, | ||
_.pickBy(_.pickBy(stageStack.Resources, [ 'Type', 'AWS::Lambda::Permission' ]), | ||
[ 'Properties.Principal', 'sns.amazonaws.com' ])); | ||
|
||
// Adjust permission to reference the function aliases | ||
_.forOwn(snsLambdaPermissions, (permission, name) => { | ||
const functionName = _.replace(name, /LambdaPermission.*$/, ''); | ||
const versionName = _.find(_.keys(versions), version => _.startsWith(version, functionName)); | ||
const aliasName = _.find(_.keys(aliases), alias => _.startsWith(alias, functionName)); | ||
|
||
// Adjust references and alias permissions | ||
permission.Properties.FunctionName = { Ref: aliasName }; | ||
|
||
// Add dependency on function version | ||
permission.DependsOn = [ versionName, aliasName ]; | ||
|
||
delete stageStack.Resources[name]; | ||
}); | ||
|
||
// Add all alias stack owned resources | ||
aliasResources.push(snsTopics); | ||
aliasResources.push(snsLambdaPermissions); | ||
|
||
_.forEach(aliasResources, resource => _.assign(aliasStack.Resources, resource)); | ||
|
||
return BbPromise.resolve([ currentTemplate, aliasStackTemplates, currentAliasStackTemplate ]); | ||
}; |