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

Allow Fn::Join in stream event arns #6064

Merged
merged 3 commits into from
Apr 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/providers/aws/events/streams.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ functions:
type: kinesis type: kinesis
arn: arn:
Fn::ImportValue: MyExportedKinesisStreamArnId Fn::ImportValue: MyExportedKinesisStreamArnId
- stream
type: kinesis
arn:
Fn::Join:
- ":"
- - arn
- aws
- kinesis
- Ref: AWS::Region
- Ref: AWS::AccountId
- stream/MyOtherKinesisStream
``` ```


## Setting the BatchSize and StartingPosition ## Setting the BatchSize and StartingPosition
Expand Down
18 changes: 13 additions & 5 deletions lib/plugins/aws/package/compile/events/stream/index.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -70,13 +70,14 @@ class AwsCompileStreamEvents {
.Error(errorMessage); .Error(errorMessage);
} }
if (Object.keys(event.stream.arn).length !== 1 if (Object.keys(event.stream.arn).length !== 1
|| !(_.has(event.stream.arn, 'Fn::ImportValue') || !(_.has(event.stream.arn, 'Fn::ImportValue')
|| _.has(event.stream.arn, 'Fn::GetAtt'))) { || _.has(event.stream.arn, 'Fn::GetAtt')
|| _.has(event.stream.arn, 'Fn::Join'))) {
const errorMessage = [ const errorMessage = [
`Bad dynamic ARN property on stream event in function "${functionName}"`, `Bad dynamic ARN property on stream event in function "${functionName}"`,
' If you use a dynamic "arn" (such as with Fn::GetAtt or Fn::ImportValue)', ' If you use a dynamic "arn" (such as with Fn::GetAtt, Fn::Join',
' there must only be one key (either Fn::GetAtt or Fn::ImportValue) in the arn', ' or Fn::ImportValue) there must only be one key (either Fn::GetAtt, Fn::Join',
' object. Please check the docs for more info.', ' or Fn::ImportValue) in the arn object. Please check the docs for more info.',
].join(''); ].join('');
throw new this.serverless.classes throw new this.serverless.classes
.Error(errorMessage); .Error(errorMessage);
Expand Down Expand Up @@ -109,6 +110,13 @@ class AwsCompileStreamEvents {
return EventSourceArn['Fn::GetAtt'][0]; return EventSourceArn['Fn::GetAtt'][0];
} else if (EventSourceArn['Fn::ImportValue']) { } else if (EventSourceArn['Fn::ImportValue']) {
return EventSourceArn['Fn::ImportValue']; return EventSourceArn['Fn::ImportValue'];
} else if (EventSourceArn['Fn::Join']) {
// [0] is the used delimiter, [1] is the array with values
const name = EventSourceArn['Fn::Join'][1].slice(-1).pop();
if (name.split('/').length) {
return name.split('/').pop();
}
return name;
} }
return EventSourceArn.split('/')[1]; return EventSourceArn.split('/')[1];
}()); }());
Expand Down
97 changes: 69 additions & 28 deletions lib/plugins/aws/package/compile/events/stream/index.test.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -337,21 +337,21 @@ describe('AwsCompileStreamEvents', () => {
.Properties.EventSourceArn .Properties.EventSourceArn
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[0] awsCompileStreamEvents.serverless.service.functions.first.events[0]
.stream.arn .stream.arn
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbFoo .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbFoo
.Properties.BatchSize .Properties.BatchSize
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[0] awsCompileStreamEvents.serverless.service.functions.first.events[0]
.stream.batchSize .stream.batchSize
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbFoo .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbFoo
.Properties.StartingPosition .Properties.StartingPosition
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[0] awsCompileStreamEvents.serverless.service.functions.first.events[0]
.stream.startingPosition .stream.startingPosition
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbFoo .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbFoo
Expand All @@ -372,7 +372,7 @@ describe('AwsCompileStreamEvents', () => {
.Properties.EventSourceArn .Properties.EventSourceArn
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[1] awsCompileStreamEvents.serverless.service.functions.first.events[1]
.stream.arn .stream.arn
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbBar .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbBar
Expand Down Expand Up @@ -401,7 +401,7 @@ describe('AwsCompileStreamEvents', () => {
.Properties.EventSourceArn .Properties.EventSourceArn
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[2] awsCompileStreamEvents.serverless.service.functions.first.events[2]
.stream .stream
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbBaz .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingDynamodbBaz
Expand Down Expand Up @@ -433,13 +433,30 @@ describe('AwsCompileStreamEvents', () => {
type: 'kinesis', type: 'kinesis',
}, },
}, },
{
stream: {
arn: {
'Fn::Join': [
':', [
'arn', 'aws', 'kinesis', {
Ref: 'AWS::Region',
}, {
Ref: 'AWS::AccountId',
},
'stream/MyStream',
],
],
},
type: 'kinesis',
},
},
], ],
}, },
}; };


awsCompileStreamEvents.compileStreamEvents(); awsCompileStreamEvents.compileStreamEvents();


// dynamodb version // dynamodb with Fn::GetAtt
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources .provider.compiledCloudFormationTemplate.Resources
.FirstEventSourceMappingDynamodbSomeDdbTable.Properties.EventSourceArn .FirstEventSourceMappingDynamodbSomeDdbTable.Properties.EventSourceArn
Expand Down Expand Up @@ -468,13 +485,36 @@ describe('AwsCompileStreamEvents', () => {
], ],
} }
); );
// and now kinesis
// kinesis with Fn::ImportValue
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources .provider.compiledCloudFormationTemplate.Resources
.FirstEventSourceMappingKinesisForeignKinesis.Properties.EventSourceArn .FirstEventSourceMappingKinesisForeignKinesis.Properties.EventSourceArn
).to.deep.equal( ).to.deep.equal(
{ 'Fn::ImportValue': 'ForeignKinesis' } { 'Fn::ImportValue': 'ForeignKinesis' }
); );

// kinesis with Fn::Join
expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources
.FirstEventSourceMappingKinesisMyStream.Properties.EventSourceArn
).to.deep.equal(
{
'Fn::Join': [
':', [
'arn',
'aws',
'kinesis',
{
Ref: 'AWS::Region',
}, {
Ref: 'AWS::AccountId',
},
'stream/MyStream',
],
],
}
);
}); });


it('fails if Fn::GetAtt/dynamic stream ARN is used without a type', () => { it('fails if Fn::GetAtt/dynamic stream ARN is used without a type', () => {
Expand All @@ -493,25 +533,26 @@ describe('AwsCompileStreamEvents', () => {
expect(() => awsCompileStreamEvents.compileStreamEvents()).to.throw(Error); expect(() => awsCompileStreamEvents.compileStreamEvents()).to.throw(Error);
}); });


it('fails if keys other than Fn::GetAtt/ImportValue are used for dynamic stream ARN', () => { it('fails if keys other than Fn::GetAtt/ImportValue/Join are used for dynamic stream ARN',
awsCompileStreamEvents.serverless.service.functions = { () => {
first: { awsCompileStreamEvents.serverless.service.functions = {
events: [ first: {
{ events: [
stream: { {
type: 'dynamodb', stream: {
arn: { type: 'dynamodb',
'Fn::GetAtt': ['SomeDdbTable', 'StreamArn'], arn: {
batchSize: 1, 'Fn::GetAtt': ['SomeDdbTable', 'StreamArn'],
batchSize: 1,
},
}, },
}, },
}, ],
], },
}, };
};


expect(() => awsCompileStreamEvents.compileStreamEvents()).to.throw(Error); expect(() => awsCompileStreamEvents.compileStreamEvents()).to.throw(Error);
}); });


it('should add the necessary IAM role statements', () => { it('should add the necessary IAM role statements', () => {
awsCompileStreamEvents.serverless.service.functions = { awsCompileStreamEvents.serverless.service.functions = {
Expand Down Expand Up @@ -594,21 +635,21 @@ describe('AwsCompileStreamEvents', () => {
.Properties.EventSourceArn .Properties.EventSourceArn
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[0] awsCompileStreamEvents.serverless.service.functions.first.events[0]
.stream.arn .stream.arn
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisFoo .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisFoo
.Properties.BatchSize .Properties.BatchSize
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[0] awsCompileStreamEvents.serverless.service.functions.first.events[0]
.stream.batchSize .stream.batchSize
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisFoo .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisFoo
.Properties.StartingPosition .Properties.StartingPosition
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[0] awsCompileStreamEvents.serverless.service.functions.first.events[0]
.stream.startingPosition .stream.startingPosition
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisFoo .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisFoo
Expand All @@ -629,7 +670,7 @@ describe('AwsCompileStreamEvents', () => {
.Properties.EventSourceArn .Properties.EventSourceArn
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[1] awsCompileStreamEvents.serverless.service.functions.first.events[1]
.stream.arn .stream.arn
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisBar .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisBar
Expand Down Expand Up @@ -658,7 +699,7 @@ describe('AwsCompileStreamEvents', () => {
.Properties.EventSourceArn .Properties.EventSourceArn
).to.equal( ).to.equal(
awsCompileStreamEvents.serverless.service.functions.first.events[2] awsCompileStreamEvents.serverless.service.functions.first.events[2]
.stream .stream
); );
expect(awsCompileStreamEvents.serverless.service expect(awsCompileStreamEvents.serverless.service
.provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisBaz .provider.compiledCloudFormationTemplate.Resources.FirstEventSourceMappingKinesisBaz
Expand Down