Skip to content

Commit 17e9737

Browse files
committed
Merge remote-tracking branch 'origin/master' into correct-typo
2 parents e4db500 + 0f04931 commit 17e9737

File tree

13 files changed

+198
-105
lines changed

13 files changed

+198
-105
lines changed

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
# 1.46.0 (2019-06-26)
2+
3+
- [Fix formatting issue with Markdown link](https://github.com/serverless/serverless/pull/6228)
4+
- [Update docs | dont use provider.tags with shared API Gateway](https://github.com/serverless/serverless/pull/6225)
5+
- [Fix: Update azure template](https://github.com/serverless/serverless/pull/6258)
6+
- [Improve user message](https://github.com/serverless/serverless/pull/6254)
7+
- [Reference custom ApiGateway for models and request validators if conf…](https://github.com/serverless/serverless/pull/6231)
8+
- [Ensure integration tests do not fail when run concurrently](https://github.com/serverless/serverless/pull/6256)
9+
- [Improve integration test experience](https://github.com/serverless/serverless/pull/6253)
10+
- [Fix lambda integration timeout response template](https://github.com/serverless/serverless/pull/6255)
11+
- [Fix duplicate packaging issue](https://github.com/serverless/serverless/pull/6244)
12+
- [Fix Travis configuration for branch/tag runs](https://github.com/serverless/serverless/pull/6265)
13+
- [fixed a typo 🖊](https://github.com/serverless/serverless/pull/6275)
14+
- [Fix #6267](https://github.com/serverless/serverless/pull/6268)
15+
- [#6017 Allow to load plugin from path](https://github.com/serverless/serverless/pull/6261)
16+
- [Added correction based on community feedback](https://github.com/serverless/serverless/pull/6286)
17+
- [Remove package-lock.json and shrinkwrap scripts](https://github.com/serverless/serverless/pull/6280)
18+
- [Remove README redundant link](https://github.com/serverless/serverless/pull/6288)
19+
- [Remove default stage value in provider object](https://github.com/serverless/serverless/pull/6200)
20+
- [Use naming to get stackName](https://github.com/serverless/serverless/pull/6285)
21+
- [Fix typo in link to ALB docs](https://github.com/serverless/serverless/pull/6292)
22+
- [Add ip, method, header and query conditions to ALB events](https://github.com/serverless/serverless/pull/6293)
23+
- [Feature/support external websocket api](https://github.com/serverless/serverless/pull/6272)
24+
25+
## Meta
26+
- [Comparison since last release](https://github.com/serverless/serverless/compare/v1.45.1...v1.46.0)
27+
128
# 1.45.1 (2019-06-12)
229

330
- [Fix IAM policies setup for functions with custom name](https://github.com/serverless/serverless/pull/6240)

docs/providers/aws/guide/serverless.yml.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ provider:
6060
restApiResources: # List of existing resources that were created in the REST API. This is required or the stack will be conflicted
6161
'/users': xxxxxxxxxx
6262
'/users/create': xxxxxxxxxx
63+
websocketApiId: # Websocket API resource ID. Default is generated by the framewok
6364
apiKeySourceType: HEADER # Source of API key for usage plan. HEADER or AUTHORIZER.
6465
minimumCompressionSize: 1024 # Compress response when larger than specified size in bytes (must be between 0 and 10485760)
6566
description: Some Description # Optional description for the API Gateway stage deployment

lib/plugins/aws/package/compile/events/websockets/lib/api.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ const BbPromise = require('bluebird');
55

66
module.exports = {
77
compileApi() {
8+
const apiGateway = this.serverless.service.provider.apiGateway || {};
9+
10+
// immediately return if we're using an external websocket API id
11+
if (apiGateway.websocketApiId) {
12+
return BbPromise.resolve();
13+
}
14+
815
this.websocketsApiLogicalId = this.provider.naming.getWebsocketsApiLogicalId();
916

1017
const RouteSelectionExpression = this.serverless.service.provider

lib/plugins/aws/package/compile/events/websockets/lib/api.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ describe('#compileApi()', () => {
5050
});
5151
}));
5252

53+
it('should ignore API resource creation if there is predefined websocketApi config', () => {
54+
awsCompileWebsocketsEvents.serverless.service.provider.apiGateway = {
55+
websocketApiId: '5ezys3sght',
56+
};
57+
return awsCompileWebsocketsEvents.compileApi().then(() => {
58+
const resources = awsCompileWebsocketsEvents.serverless.service.provider
59+
.compiledCloudFormationTemplate.Resources;
60+
61+
expect(resources).to.not.have.property('WebsocketsApi');
62+
});
63+
});
64+
5365
it('should add the websockets policy', () => awsCompileWebsocketsEvents
5466
.compileApi().then(() => {
5567
const resources = awsCompileWebsocketsEvents.serverless.service.provider

lib/plugins/aws/package/compile/events/websockets/lib/authorizers.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ module.exports = {
1616
[websocketsAuthorizerLogicalId]: {
1717
Type: 'AWS::ApiGatewayV2::Authorizer',
1818
Properties: {
19-
ApiId: {
20-
Ref: this.websocketsApiLogicalId,
21-
},
19+
ApiId: this.provider.getApiGatewayWebsocketApiId(),
2220
Name: event.authorizer.name,
2321
AuthorizerType: 'REQUEST',
2422
AuthorizerUri: event.authorizer.uri,

lib/plugins/aws/package/compile/events/websockets/lib/authorizers.test.js

Lines changed: 122 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -8,102 +8,141 @@ const AwsProvider = require('../../../../../provider/awsProvider');
88
describe('#compileAuthorizers()', () => {
99
let awsCompileWebsocketsEvents;
1010

11-
beforeEach(() => {
12-
const serverless = new Serverless();
13-
serverless.setProvider('aws', new AwsProvider(serverless));
14-
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
11+
describe('for routes with authorizer definition', () => {
12+
beforeEach(() => {
13+
const serverless = new Serverless();
14+
serverless.setProvider('aws', new AwsProvider(serverless));
15+
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
1516

16-
awsCompileWebsocketsEvents = new AwsCompileWebsocketsEvents(serverless);
17+
awsCompileWebsocketsEvents = new AwsCompileWebsocketsEvents(serverless);
1718

18-
awsCompileWebsocketsEvents.websocketsApiLogicalId
19-
= awsCompileWebsocketsEvents.provider.naming.getWebsocketsApiLogicalId();
20-
});
19+
awsCompileWebsocketsEvents.websocketsApiLogicalId
20+
= awsCompileWebsocketsEvents.provider.naming.getWebsocketsApiLogicalId();
2121

22-
it('should create an authorizer resource for routes with authorizer definition', () => {
23-
awsCompileWebsocketsEvents.validated = {
24-
events: [
25-
{
26-
functionName: 'First',
27-
route: '$connect',
28-
authorizer: {
29-
name: 'auth',
30-
uri: {
31-
'Fn::Join': ['',
32-
[
33-
'arn:',
34-
{ Ref: 'AWS::Partition' },
35-
':apigateway:',
36-
{ Ref: 'AWS::Region' },
37-
':lambda:path/2015-03-31/functions/',
38-
{ 'Fn::GetAtt': ['AuthLambdaFunction', 'Arn'] },
39-
'/invocations',
22+
awsCompileWebsocketsEvents.validated = {
23+
events: [
24+
{
25+
functionName: 'First',
26+
route: '$connect',
27+
authorizer: {
28+
name: 'auth',
29+
uri: {
30+
'Fn::Join': ['',
31+
[
32+
'arn:',
33+
{ Ref: 'AWS::Partition' },
34+
':apigateway:',
35+
{ Ref: 'AWS::Region' },
36+
':lambda:path/2015-03-31/functions/',
37+
{ 'Fn::GetAtt': ['AuthLambdaFunction', 'Arn'] },
38+
'/invocations',
39+
],
4040
],
41-
],
41+
},
42+
identitySource: ['route.request.header.Auth'],
4243
},
43-
identitySource: ['route.request.header.Auth'],
4444
},
45-
},
46-
],
47-
};
48-
49-
return awsCompileWebsocketsEvents.compileAuthorizers().then(() => {
50-
const resources = awsCompileWebsocketsEvents.serverless.service.provider
51-
.compiledCloudFormationTemplate.Resources;
52-
53-
expect(resources).to.deep.equal({
54-
AuthWebsocketsAuthorizer: {
55-
Type: 'AWS::ApiGatewayV2::Authorizer',
56-
Properties: {
57-
ApiId: {
58-
Ref: 'WebsocketsApi',
59-
},
60-
Name: 'auth',
61-
AuthorizerType: 'REQUEST',
62-
AuthorizerUri: {
63-
'Fn::Join': [
64-
'',
65-
[
66-
'arn:',
67-
{
68-
Ref: 'AWS::Partition',
69-
},
70-
':apigateway:',
71-
{
72-
Ref: 'AWS::Region',
73-
},
74-
':lambda:path/2015-03-31/functions/',
75-
{
76-
'Fn::GetAtt': [
77-
'AuthLambdaFunction',
78-
'Arn',
79-
],
80-
},
81-
'/invocations',
45+
],
46+
};
47+
});
48+
49+
it('should create an authorizer resource', () => {
50+
return awsCompileWebsocketsEvents.compileAuthorizers().then(() => {
51+
const resources = awsCompileWebsocketsEvents.serverless.service.provider
52+
.compiledCloudFormationTemplate.Resources;
53+
54+
expect(resources).to.deep.equal({
55+
AuthWebsocketsAuthorizer: {
56+
Type: 'AWS::ApiGatewayV2::Authorizer',
57+
Properties: {
58+
ApiId: {
59+
Ref: 'WebsocketsApi',
60+
},
61+
Name: 'auth',
62+
AuthorizerType: 'REQUEST',
63+
AuthorizerUri: {
64+
'Fn::Join': [
65+
'',
66+
[
67+
'arn:',
68+
{
69+
Ref: 'AWS::Partition',
70+
},
71+
':apigateway:',
72+
{
73+
Ref: 'AWS::Region',
74+
},
75+
':lambda:path/2015-03-31/functions/',
76+
{
77+
'Fn::GetAtt': [
78+
'AuthLambdaFunction',
79+
'Arn',
80+
],
81+
},
82+
'/invocations',
83+
],
8284
],
83-
],
85+
},
86+
IdentitySource: ['route.request.header.Auth'],
8487
},
85-
IdentitySource: ['route.request.header.Auth'],
8688
},
87-
},
89+
});
90+
});
91+
});
92+
93+
it('should use existing Api if there is predefined websocketApi config', () => {
94+
awsCompileWebsocketsEvents.serverless.service.provider.apiGateway = {
95+
websocketApiId: '5ezys3sght',
96+
};
97+
98+
return awsCompileWebsocketsEvents.compileAuthorizers().then(() => {
99+
const resources = awsCompileWebsocketsEvents.serverless.service.provider
100+
.compiledCloudFormationTemplate.Resources;
101+
102+
expect(resources.AuthWebsocketsAuthorizer.Properties).to.contain({
103+
ApiId: '5ezys3sght',
104+
});
88105
});
89106
});
90107
});
91108

92-
it('should NOT create an authorizer resource for routes with not authorizer definition', () => {
93-
awsCompileWebsocketsEvents.validated = {
94-
events: [
95-
{
96-
functionName: 'First',
97-
route: '$connect',
98-
},
99-
],
100-
};
101-
102-
return awsCompileWebsocketsEvents.compileAuthorizers().then(() => {
103-
const resources = awsCompileWebsocketsEvents.serverless.service.provider
104-
.compiledCloudFormationTemplate.Resources;
105-
106-
expect(resources).to.deep.equal({});
109+
describe('for routes without authorizer definition', () => {
110+
beforeEach(() => {
111+
const serverless = new Serverless();
112+
serverless.setProvider('aws', new AwsProvider(serverless));
113+
serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} };
114+
115+
awsCompileWebsocketsEvents = new AwsCompileWebsocketsEvents(serverless);
116+
117+
awsCompileWebsocketsEvents.websocketsApiLogicalId
118+
= awsCompileWebsocketsEvents.provider.naming.getWebsocketsApiLogicalId();
119+
120+
awsCompileWebsocketsEvents.validated = {
121+
events: [
122+
{
123+
functionName: 'First',
124+
route: '$connect',
125+
},
126+
],
127+
};
128+
});
129+
130+
it('should NOT create an authorizer resource for routes with not authorizer definition', () => {
131+
awsCompileWebsocketsEvents.validated = {
132+
events: [
133+
{
134+
functionName: 'First',
135+
route: '$connect',
136+
},
137+
],
138+
};
139+
140+
return awsCompileWebsocketsEvents.compileAuthorizers().then(() => {
141+
const resources = awsCompileWebsocketsEvents.serverless.service.provider
142+
.compiledCloudFormationTemplate.Resources;
143+
144+
expect(resources).to.deep.equal({});
145+
});
107146
});
108147
});
109148
});

lib/plugins/aws/package/compile/events/websockets/lib/deployment.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ module.exports = {
1818
Type: 'AWS::ApiGatewayV2::Deployment',
1919
DependsOn: routeLogicalIds,
2020
Properties: {
21-
ApiId: {
22-
Ref: this.websocketsApiLogicalId,
23-
},
21+
ApiId: this.provider.getApiGatewayWebsocketApiId(),
2422
Description: this.serverless.service.provider
2523
.websocketsDescription || 'Serverless Websockets',
2624
},
@@ -34,7 +32,7 @@ module.exports = {
3432
'Fn::Join': ['',
3533
[
3634
'wss://',
37-
{ Ref: this.provider.naming.getWebsocketsApiLogicalId() },
35+
this.provider.getApiGatewayWebsocketApiId(),
3836
'.execute-api.',
3937
{ Ref: 'AWS::Region' },
4038
'.',

lib/plugins/aws/package/compile/events/websockets/lib/integrations.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ module.exports = {
1414
[websocketsIntegrationLogicalId]: {
1515
Type: 'AWS::ApiGatewayV2::Integration',
1616
Properties: {
17-
ApiId: {
18-
Ref: this.websocketsApiLogicalId,
19-
},
17+
ApiId: this.provider.getApiGatewayWebsocketApiId(),
2018
IntegrationType: 'AWS_PROXY',
2119
IntegrationUri: {
2220
'Fn::Join': ['',

lib/plugins/aws/package/compile/events/websockets/lib/permissions.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const BbPromise = require('bluebird');
66
module.exports = {
77
compilePermissions() {
88
this.validated.events.forEach(event => {
9+
const websocketApiId = this.provider.getApiGatewayWebsocketApiId();
910
const lambdaLogicalId = this.provider.naming.getLambdaLogicalId(event.functionName);
1011

1112
const websocketsPermissionLogicalId = this.provider.naming
@@ -14,7 +15,9 @@ module.exports = {
1415
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources, {
1516
[websocketsPermissionLogicalId]: {
1617
Type: 'AWS::Lambda::Permission',
17-
DependsOn: [this.websocketsApiLogicalId, lambdaLogicalId],
18+
DependsOn: (websocketApiId.Ref !== undefined)
19+
? [websocketApiId.Ref, lambdaLogicalId]
20+
: [lambdaLogicalId],
1821
Properties: {
1922
FunctionName: {
2023
'Fn::GetAtt': [lambdaLogicalId, 'Arn'],
@@ -32,7 +35,9 @@ module.exports = {
3235
const authorizerPermissionTemplate = {
3336
[websocketsAuthorizerPermissionLogicalId]: {
3437
Type: 'AWS::Lambda::Permission',
35-
DependsOn: [this.websocketsApiLogicalId],
38+
DependsOn: (websocketApiId.Ref !== undefined)
39+
? [websocketApiId.Ref]
40+
: [],
3641
Properties: {
3742
Action: 'lambda:InvokeFunction',
3843
Principal: 'apigateway.amazonaws.com',

lib/plugins/aws/package/compile/events/websockets/lib/routes.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ module.exports = {
1616
[websocketsRouteLogicalId]: {
1717
Type: 'AWS::ApiGatewayV2::Route',
1818
Properties: {
19-
ApiId: {
20-
Ref: this.websocketsApiLogicalId,
21-
},
19+
ApiId: this.provider.getApiGatewayWebsocketApiId(),
2220
RouteKey: event.route,
2321
AuthorizationType: 'NONE',
2422
Target: {

0 commit comments

Comments
 (0)