Skip to content

Commit 102fe13

Browse files
authored
run interceptRequest async + change BUCKET_MARKER_LOCAL default to 'hot-reload' (#219)
1 parent 3ac7019 commit 102fe13

File tree

6 files changed

+47
-23
lines changed

6 files changed

+47
-23
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ custom:
206206
207207
## Change Log
208208
209+
* v1.1.0: Fix SSM environment variables resolving issues with serverless v3, change default for `BUCKET_MARKER_LOCAL` to `hot-reload`
209210
* v1.0.6: Add `BUCKET_MARKER_LOCAL` configuration for customizing S3 bucket for lambda mount and [Hot Reloading](https://docs.localstack.cloud/user-guide/tools/lambda-tools/hot-reloading/).
210211
* v1.0.5: Fix S3 Bucket LocationConstraint issue when the provider region is `us-east-1`
211212
* v1.0.4: Fix IPv4 fallback check to prevent IPv6 connection issue with `localhost` on macOS

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "serverless-localstack",
3-
"version": "1.0.6",
3+
"version": "1.1.0",
44
"description": "Connect Serverless to LocalStack!",
55
"main": "src/index.js",
66
"scripts": {

spec/helpers/services.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ const defaultConfig = {
1414
provider: {
1515
name: 'aws',
1616
runtime: 'nodejs12.x',
17-
lambdaHashingVersion: '20201221'
17+
lambdaHashingVersion: '20201221',
18+
environment: {
19+
LAMBDA_STAGE: '${ssm:/${opt:stage, self:provider.stage}/lambda/common/LAMBDA_STAGE}'
20+
}
1821
},
1922
plugins: [
2023
'serverless-localstack'

spec/integration/integration.spec.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,33 @@
33
const services = require('../helpers/services');
44

55
const LONG_TIMEOUT = 30000;
6+
const AWS = require('aws-sdk');
7+
8+
// Set the region and endpoint in the config for LocalStack
9+
AWS.config.update({
10+
region: 'us-east-1',
11+
endpoint: 'http://localhost:4566'
12+
});
13+
AWS.config.credentials = new AWS.Credentials({
14+
accessKeyId: 'test',
15+
secretAccessKey: 'test',
16+
});
17+
18+
const ssm = new AWS.SSM();
19+
20+
const params = {
21+
Name: '/dev/lambda/common/LAMBDA_STAGE',
22+
Type: 'String',
23+
Value: 'my-value',
24+
Overwrite: true
25+
};
626

727
describe('LocalstackPlugin', () => {
828

9-
beforeEach( () => {
10-
this.service = services.createService({});
29+
beforeEach(
30+
async () => {
31+
await ssm.putParameter(params).promise();
32+
this.service = services.createService({});
1133
});
1234

1335
afterEach( () => {
@@ -18,4 +40,4 @@ describe('LocalstackPlugin', () => {
1840
services.deployService(this.service);
1941
}, LONG_TIMEOUT);
2042

21-
});
43+
});

spec/unit/index.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ describe("LocalstackPlugin", () => {
171171
instance = new LocalstackPlugin(serverless, defaultPluginState);
172172
await simulateBeforeDeployHooks(instance);
173173

174-
awsProvider.request('s3', 'foo', {
174+
await awsProvider.request('s3', 'foo', {
175175
TemplateURL: pathToTemplate
176176
});
177177
expect(request.called).to.be.true;
@@ -184,7 +184,7 @@ describe("LocalstackPlugin", () => {
184184
instance = new LocalstackPlugin(serverless, defaultPluginState)
185185
await simulateBeforeDeployHooks(instance);
186186

187-
awsProvider.request('S3', 'validateTemplate', {});
187+
await awsProvider.request('S3', 'validateTemplate', {});
188188

189189
expect(request.called).to.be.false;
190190
});

src/index.js

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ class LocalstackPlugin {
3232

3333
this.serverless = serverless;
3434
this.options = options;
35-
36-
this.hooks = {};
35+
this.hooks = {'initialize': () => this.init()};
3736
// Define a before-hook for all event types
3837
for (let event in this.serverless.pluginManager.hooks) {
3938
const doAdd = event.startsWith('before:');
@@ -152,6 +151,10 @@ class LocalstackPlugin {
152151
}
153152
}
154153

154+
async init() {
155+
await this.reconfigureAWS()
156+
}
157+
155158
addHookInFirstPosition(eventName, hookFunction) {
156159
this.serverless.pluginManager.hooks[eventName] = this.serverless.pluginManager.hooks[eventName] || [];
157160
this.serverless.pluginManager.hooks[eventName].unshift(
@@ -172,16 +175,6 @@ class LocalstackPlugin {
172175
awsProvider.request = this.interceptRequest.bind(this);
173176
}
174177

175-
// Reconfigure AWS clients
176-
try {
177-
this.reconfigureAWS();
178-
} catch (e) {
179-
// This can happen if we are executing in the plugin initialization context and
180-
// the template variables have not been fully initialized yet
181-
// (e.g., "Error: Profile ${self:custom.stage}Profile does not exist")
182-
return;
183-
}
184-
185178
// Patch plugin methods
186179
this.skipIfMountLambda('Package', 'packageService');
187180
function compileFunction(functionName) {
@@ -196,8 +189,7 @@ class LocalstackPlugin {
196189
Object.keys(resources).forEach(id => {
197190
const res = resources[id];
198191
if (res.Type === 'AWS::Lambda::Function') {
199-
// TODO: change the default BUCKET_MARKER_LOCAL to 'hot-reload'
200-
res.Properties.Code.S3Bucket = process.env.BUCKET_MARKER_LOCAL || '__local__'; // for now, the default is still __local__
192+
res.Properties.Code.S3Bucket = process.env.BUCKET_MARKER_LOCAL || 'hot-reload'; // default changed to 'hot-reload' with LS v2 release
201193
res.Properties.Code.S3Key = process.cwd();
202194
const mountCode = this.config.lambda.mountCode;
203195
if (typeof mountCode === 'string' && mountCode.toLowerCase() !== 'true') {
@@ -574,6 +566,10 @@ class LocalstackPlugin {
574566
*/
575567
async reconfigureAWS() {
576568
if(this.isActive()) {
569+
if(this.reconfiguredEndpoints){
570+
this.debug("Skipping reconfiguring of endpoints (already reconfigured)")
571+
return;
572+
}
577573
this.log('Using serverless-localstack');
578574
const hostname = await this.getConnectHostname();
579575
const host = `http://${hostname}`;
@@ -627,6 +623,8 @@ class LocalstackPlugin {
627623
// required for compatibility with certain plugin, e.g., serverless-domain-manager
628624
awsProvider.cachedCredentials.endpoint = localEndpoint;
629625
}
626+
this.log("serverless-localstack: Reconfigured endpoints")
627+
this.reconfiguredEndpoints = true;
630628
}
631629
else {
632630
this.endpoints = {}
@@ -656,14 +654,13 @@ class LocalstackPlugin {
656654
}
657655
}
658656

659-
interceptRequest(service, method, params) {
657+
async interceptRequest(service, method, params) {
660658

661659
// Enable the plugin here, if not yet enabled (the function call below is idempotent).
662660
// TODO: It seems that we can potentially remove the hooks / plugin loading logic
663661
// entirely and only rely on activating the -> we should evaluate this, as it would
664662
// substantially simplify the code in this file.
665663
this.beforeEventHook();
666-
667664
// Template validation is not supported in LocalStack
668665
if (method == "validateTemplate") {
669666
this.log('Skipping template validation: Unsupported in Localstack');
@@ -679,6 +676,7 @@ class LocalstackPlugin {
679676
params.TemplateURL = params.TemplateURL.replace(/https:\/\/s3.amazonaws.com/, config.s3.endpoint);
680677
}
681678
}
679+
await this.reconfigureAWS();
682680

683681
return this.awsProviderRequest(service, method, params);
684682
}

0 commit comments

Comments
 (0)