From df7692ac809ead5febe1f59645ad9c3c901dcd3a Mon Sep 17 00:00:00 2001 From: Philipp Muens Date: Fri, 14 Oct 2016 18:14:30 -0700 Subject: [PATCH 1/8] Introduce AwsProvider plugin --- lib/Serverless.js | 10 +++ .../Serverless.js => lib/Serverless.test.js | 48 ++++++++-- lib/plugins/Plugins.json | 1 + lib/plugins/aws/deploy/index.js | 4 +- lib/plugins/aws/deploy/lib/cleanupS3Bucket.js | 4 +- lib/plugins/aws/deploy/lib/configureStack.js | 2 +- lib/plugins/aws/deploy/lib/createStack.js | 4 +- lib/plugins/aws/deploy/lib/setBucketName.js | 2 +- lib/plugins/aws/deploy/lib/updateStack.js | 2 +- lib/plugins/aws/deploy/lib/uploadArtifacts.js | 4 +- .../aws/deploy/tests/cleanupS3Bucket.js | 24 ++--- .../aws/deploy/tests/configureStack.js | 89 ++++++++++--------- lib/plugins/aws/deploy/tests/createStack.js | 20 +++-- lib/plugins/aws/deploy/tests/setBucketName.js | 8 +- lib/plugins/aws/deploy/tests/updateStack.js | 8 +- .../aws/deploy/tests/uploadArtifacts.js | 14 +-- lib/plugins/aws/deployFunction/index.js | 7 +- lib/plugins/aws/deployFunction/tests/index.js | 24 +++-- lib/plugins/aws/info/index.js | 11 ++- lib/plugins/aws/info/tests/index.js | 24 ++--- lib/plugins/aws/invoke/index.js | 5 +- lib/plugins/aws/invoke/tests/index.js | 10 ++- lib/plugins/aws/lib/monitorStack.js | 2 +- lib/plugins/aws/logs/index.js | 7 +- lib/plugins/aws/logs/tests/index.js | 20 +++-- lib/plugins/aws/remove/index.js | 4 +- lib/plugins/aws/remove/lib/bucket.js | 6 +- lib/plugins/aws/remove/lib/stack.js | 2 +- lib/plugins/aws/remove/tests/bucket.js | 18 ++-- lib/plugins/aws/remove/tests/stack.js | 6 +- lib/plugins/aws/tests/monitorStack.js | 40 ++++----- .../index.js => awsProvider/awsProvider.js} | 9 +- .../awsProvider.test.js} | 86 +++++++++--------- tests/all.js | 4 +- 34 files changed, 297 insertions(+), 232 deletions(-) rename tests/classes/Serverless.js => lib/Serverless.test.js (84%) rename lib/plugins/{aws/index.js => awsProvider/awsProvider.js} (98%) rename lib/plugins/{aws/tests/index.js => awsProvider/awsProvider.test.js} (78%) diff --git a/lib/Serverless.js b/lib/Serverless.js index cd4fa678e..bc9bdf814 100644 --- a/lib/Serverless.js +++ b/lib/Serverless.js @@ -20,6 +20,8 @@ class Serverless { let configObject = config; configObject = configObject || {}; + this.providers = {}; + this.version = Version; this.yamlParser = new YamlParser(this); @@ -90,6 +92,14 @@ class Serverless { return this.pluginManager.run(this.processedInput.commands); } + setProvider(name, provider) { + this.providers[name] = provider; + } + + getProvider(name) { + return this.providers[name] ? this.providers[name] : false; + } + getVersion() { return this.version; } diff --git a/tests/classes/Serverless.js b/lib/Serverless.test.js similarity index 84% rename from tests/classes/Serverless.js rename to lib/Serverless.test.js index c37ae03db..25e2b7737 100644 --- a/tests/classes/Serverless.js +++ b/lib/Serverless.test.js @@ -1,18 +1,18 @@ 'use strict'; const expect = require('chai').expect; -const Serverless = require('../../lib/Serverless'); +const Serverless = require('./Serverless'); const semverRegex = require('semver-regex'); const path = require('path'); const YAML = require('js-yaml'); -const YamlParser = require('../../lib/classes/YamlParser'); -const PluginManager = require('../../lib/classes/PluginManager'); -const Utils = require('../../lib/classes/Utils'); -const Service = require('../../lib/classes/Service'); -const CLI = require('../../lib/classes/CLI'); -const Error = require('../../lib/classes/Error').SError; -const testUtils = require('../../tests/utils'); +const YamlParser = require('../lib/classes/YamlParser'); +const PluginManager = require('../lib/classes/PluginManager'); +const Utils = require('../lib/classes/Utils'); +const Service = require('../lib/classes/Service'); +const CLI = require('../lib/classes/CLI'); +const Error = require('../lib/classes/Error').SError; +const testUtils = require('../tests/utils'); describe('Serverless', () => { let serverless; @@ -37,6 +37,10 @@ describe('Serverless', () => { expect(Object.keys(serverless.config)).to.include('servicePath'); }); + it('should set an empty providers object', () => { + expect(serverless.providers).to.deep.equal({}); + }); + it('should set the Serverless version', () => { expect(serverless.version.length).to.be.at.least(1); }); @@ -194,6 +198,34 @@ describe('Serverless', () => { }); }); + describe('#setProvider()', () => { + class ProviderMock {} + + it('should set the provider object in the provider object', () => { + const myProvider = new ProviderMock(); + + serverless.setProvider('myProvider', myProvider); + + expect(serverless.providers.myProvider).to.equal(myProvider); + }); + }); + + describe('#getProvider()', () => { + class ProviderMock {} + let myProvider; + + beforeEach(() => { + myProvider = new ProviderMock(); + serverless.setProvider('myProvider', myProvider); + }); + + it('should return the provider object', () => { + const retrivedProvider = serverless.getProvider('myProvider'); + + expect(retrivedProvider).to.deep.equal(myProvider); + }); + }); + describe('#getVersion()', () => { it('should get the correct Serverless version', () => { expect(semverRegex().test(serverless.getVersion())).to.equal(true); diff --git a/lib/plugins/Plugins.json b/lib/plugins/Plugins.json index a5c6bf6f9..b9eecedf4 100644 --- a/lib/plugins/Plugins.json +++ b/lib/plugins/Plugins.json @@ -9,6 +9,7 @@ "./logs/logs.js", "./remove/remove.js", "./slstats/slstats.js", + "./awsProvider/awsProvider.js", "./aws/deploy/index.js", "./aws/invoke/index.js", "./aws/info/index.js", diff --git a/lib/plugins/aws/deploy/index.js b/lib/plugins/aws/deploy/index.js index 6cb1b4840..91da5ef9e 100644 --- a/lib/plugins/aws/deploy/index.js +++ b/lib/plugins/aws/deploy/index.js @@ -12,14 +12,12 @@ const uploadArtifacts = require('./lib/uploadArtifacts'); const updateStack = require('./lib/updateStack'); const configureStack = require('./lib/configureStack'); -const SDK = require('../'); - class AwsDeploy { constructor(serverless, options) { this.serverless = serverless; this.options = options; this.provider = 'aws'; - this.sdk = new SDK(serverless); + this.aws = this.serverless.getProvider(this.provider); Object.assign( this, diff --git a/lib/plugins/aws/deploy/lib/cleanupS3Bucket.js b/lib/plugins/aws/deploy/lib/cleanupS3Bucket.js index ad92b5a37..26a69b8c9 100644 --- a/lib/plugins/aws/deploy/lib/cleanupS3Bucket.js +++ b/lib/plugins/aws/deploy/lib/cleanupS3Bucket.js @@ -9,7 +9,7 @@ module.exports = { const directoriesToKeepCount = 4; const serviceStage = `${this.serverless.service.service}/${this.options.stage}`; - return this.sdk.request('S3', + return this.aws.request('S3', 'listObjectsV2', { Bucket: this.bucketName, @@ -62,7 +62,7 @@ module.exports = { if (objectsToRemove && objectsToRemove.length) { this.serverless.cli.log('Removing old service versions...'); - return this.sdk.request('S3', + return this.aws.request('S3', 'deleteObjects', { Bucket: this.bucketName, diff --git a/lib/plugins/aws/deploy/lib/configureStack.js b/lib/plugins/aws/deploy/lib/configureStack.js index 2c96df68c..d0831dc41 100644 --- a/lib/plugins/aws/deploy/lib/configureStack.js +++ b/lib/plugins/aws/deploy/lib/configureStack.js @@ -79,7 +79,7 @@ module.exports = { if (bucketName) { return BbPromise.bind(this) .then(() => this.validateS3BucketName(bucketName)) - .then(() => this.sdk.request('S3', + .then(() => this.aws.request('S3', 'getBucketLocation', { Bucket: bucketName, diff --git a/lib/plugins/aws/deploy/lib/createStack.js b/lib/plugins/aws/deploy/lib/createStack.js index daae1c2de..be3113299 100644 --- a/lib/plugins/aws/deploy/lib/createStack.js +++ b/lib/plugins/aws/deploy/lib/createStack.js @@ -27,7 +27,7 @@ module.exports = { Tags: Object.keys(stackTags).map((key) => ({ Key: key, Value: stackTags[key] })), }; - return this.sdk.request('CloudFormation', + return this.aws.request('CloudFormation', 'createStack', params, this.options.stage, @@ -55,7 +55,7 @@ module.exports = { return BbPromise.resolve(); } - return this.sdk.request('CloudFormation', + return this.aws.request('CloudFormation', 'describeStackResources', { StackName: stackName }, this.options.stage, diff --git a/lib/plugins/aws/deploy/lib/setBucketName.js b/lib/plugins/aws/deploy/lib/setBucketName.js index 0b2995718..db7fef659 100644 --- a/lib/plugins/aws/deploy/lib/setBucketName.js +++ b/lib/plugins/aws/deploy/lib/setBucketName.js @@ -12,7 +12,7 @@ module.exports = { return BbPromise.resolve(); } - return this.sdk.getServerlessDeploymentBucketName(this.options.stage, this.options.region) + return this.aws.getServerlessDeploymentBucketName(this.options.stage, this.options.region) .then((bucketName) => { this.bucketName = bucketName; }); diff --git a/lib/plugins/aws/deploy/lib/updateStack.js b/lib/plugins/aws/deploy/lib/updateStack.js index c2e6b312e..1b74fd8cf 100644 --- a/lib/plugins/aws/deploy/lib/updateStack.js +++ b/lib/plugins/aws/deploy/lib/updateStack.js @@ -39,7 +39,7 @@ module.exports = { }); } - return this.sdk.request('CloudFormation', + return this.aws.request('CloudFormation', 'updateStack', params, this.options.stage, diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.js index 5ce7bce69..e3c66088b 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.js @@ -19,7 +19,7 @@ module.exports = { ContentType: 'application/json', }; - return this.sdk.request('S3', + return this.aws.request('S3', 'putObject', params, this.options.stage, @@ -42,7 +42,7 @@ module.exports = { ContentType: 'application/zip', }; - return this.sdk.request('S3', + return this.aws.request('S3', 'putObject', params, this.options.stage, diff --git a/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js b/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js index 61097ea46..ae98295b2 100644 --- a/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js +++ b/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js @@ -3,6 +3,7 @@ const sinon = require('sinon'); const BbPromise = require('bluebird'); const expect = require('chai').expect; +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); @@ -13,6 +14,7 @@ describe('cleanupS3Bucket', () => { beforeEach(() => { serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); serverless.service.service = 'cleanupS3Bucket'; const options = { stage: 'dev', @@ -31,7 +33,7 @@ describe('cleanupS3Bucket', () => { }; const listObjectsStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve(serviceObjects)); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve(serviceObjects)); return awsDeploy.getObjectsToRemove().then(() => { expect(listObjectsStub.calledOnce).to.be.equal(true); @@ -40,7 +42,7 @@ describe('cleanupS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(listObjectsStub.args[0][2].Prefix).to.be.equal(`${s3Key}`); expect(listObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); @@ -63,7 +65,7 @@ describe('cleanupS3Bucket', () => { }; const listObjectsStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve(serviceObjects)); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve(serviceObjects)); return awsDeploy.getObjectsToRemove().then((objectsToRemove) => { expect(objectsToRemove).to.not @@ -104,7 +106,7 @@ describe('cleanupS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(listObjectsStub.args[0][2].Prefix).to.be.equal(`${s3Key}`); expect(listObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); @@ -121,7 +123,7 @@ describe('cleanupS3Bucket', () => { }; const listObjectsStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve(serviceObjects)); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve(serviceObjects)); return awsDeploy.getObjectsToRemove().then((objectsToRemove) => { expect(objectsToRemove.length).to.equal(0); @@ -131,7 +133,7 @@ describe('cleanupS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(listObjectsStub.args[0][2].Prefix).to.be.equal(`${s3Key}`); expect(listObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); @@ -150,7 +152,7 @@ describe('cleanupS3Bucket', () => { }; const listObjectsStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve(serviceObjects)); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve(serviceObjects)); return awsDeploy.getObjectsToRemove().then((objectsToRemove) => { expect(objectsToRemove.length).to.equal(0); @@ -160,7 +162,7 @@ describe('cleanupS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(listObjectsStub.args[0][2].Prefix).to.be.equal(`${s3Key}`); expect(listObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); }); @@ -170,13 +172,13 @@ describe('cleanupS3Bucket', () => { beforeEach(() => { deleteObjectsStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); }); it('should resolve if no service objects are found in the S3 bucket', () => awsDeploy .removeObjects().then(() => { expect(deleteObjectsStub.calledOnce).to.be.equal(false); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }) ); @@ -195,7 +197,7 @@ describe('cleanupS3Bucket', () => { expect(deleteObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(deleteObjectsStub.args[0][2].Delete.Objects).to.be.equal(objectsToRemove); expect(deleteObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/deploy/tests/configureStack.js b/lib/plugins/aws/deploy/tests/configureStack.js index c5944e67d..606f8bbae 100644 --- a/lib/plugins/aws/deploy/tests/configureStack.js +++ b/lib/plugins/aws/deploy/tests/configureStack.js @@ -4,34 +4,37 @@ const sinon = require('sinon'); const BbPromise = require('bluebird'); const path = require('path'); const expect = require('chai').expect; - +const AwsProvider = require('../../../awsProvider/awsProvider'); const Serverless = require('../../../../Serverless'); -const AwsSdk = require('../'); +const validate = require('../../lib/validate'); +const configureStack = require('../lib/configureStack'); describe('#configureStack', () => { - let awsSdk; let serverless; + const awsPlugin = {}; beforeEach(() => { serverless = new Serverless(); - const options = { + awsPlugin.serverless = serverless; + awsPlugin.aws = new AwsProvider(serverless); + awsPlugin.options = { stage: 'dev', region: 'us-east-1', }; - awsSdk = new AwsSdk(serverless, options); - awsSdk.serverless.cli = new serverless.classes.CLI(); + + Object.assign(awsPlugin, configureStack, validate); }); it('should validate the region for the given S3 bucket', () => { const bucketName = 'com.serverless.deploys'; const getBucketLocationStub = sinon - .stub(awsSdk.sdk, 'request').returns( - BbPromise.resolve({ LocationConstraint: awsSdk.options.region }) + .stub(awsPlugin.aws, 'request').returns( + BbPromise.resolve({ LocationConstraint: awsPlugin.options.region }) ); - awsSdk.serverless.service.provider.deploymentBucket = bucketName; - return awsSdk.configureStack() + awsPlugin.serverless.service.provider.deploymentBucket = bucketName; + return awsPlugin.configureStack() .then(() => { expect(getBucketLocationStub.args[0][0]).to.equal('S3'); expect(getBucketLocationStub.args[0][1]).to.equal('getBucketLocation'); @@ -43,12 +46,12 @@ describe('#configureStack', () => { const bucketName = 'com.serverless.deploys'; const createStackStub = sinon - .stub(awsSdk.sdk, 'request').returns( + .stub(awsPlugin.aws, 'request').returns( BbPromise.resolve({ LocationConstraint: 'us-west-1' }) ); - awsSdk.serverless.service.provider.deploymentBucket = 'com.serverless.deploys'; - return awsSdk.configureStack() + awsPlugin.serverless.service.provider.deploymentBucket = 'com.serverless.deploys'; + return awsPlugin.configureStack() .catch((err) => { expect(createStackStub.args[0][0]).to.equal('S3'); expect(createStackStub.args[0][1]).to.equal('getBucketLocation'); @@ -60,7 +63,7 @@ describe('#configureStack', () => { it('should merge the IamRoleLambdaExecution template into the CloudFormation template', () => { - const IamRoleLambdaExecutionTemplate = awsSdk.serverless.utils.readFileSync( + const IamRoleLambdaExecutionTemplate = awsPlugin.serverless.utils.readFileSync( path.join( __dirname, '..', @@ -69,55 +72,55 @@ describe('#configureStack', () => { ) ); - return awsSdk.configureStack() + return awsPlugin.configureStack() .then(() => { - expect(awsSdk.serverless.service.provider.compiledCloudFormationTemplate + expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Resources.IamRoleLambdaExecution ).to.deep.equal(IamRoleLambdaExecutionTemplate.IamRoleLambdaExecution); }); }); it('should merge IamPolicyLambdaExecution template into the CloudFormation template', () => - awsSdk.configureStack() + awsPlugin.configureStack() .then(() => { // we check for the type here because a deep equality check will error out due to // the updates which are made after the merge (they are tested in a separate test) - expect(awsSdk.serverless.service.provider.compiledCloudFormationTemplate + expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Resources.IamPolicyLambdaExecution.Type ).to.deep.equal('AWS::IAM::Policy'); }) ); it('should update the necessary variables for the IamPolicyLambdaExecution', () => - awsSdk.configureStack() + awsPlugin.configureStack() .then(() => { - expect(awsSdk.serverless.service.provider.compiledCloudFormationTemplate + expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Resources .IamPolicyLambdaExecution .Properties .PolicyName ).to.equal( `${ - awsSdk.options.stage + awsPlugin.options.stage }-${ - awsSdk.serverless.service.service + awsPlugin.serverless.service.service }-lambda` ); - expect(awsSdk.serverless.service.provider.compiledCloudFormationTemplate + expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Resources .IamPolicyLambdaExecution .Properties .PolicyDocument .Statement[0] .Resource - ).to.equal(`arn:aws:logs:${awsSdk.options.region}:*:*`); + ).to.equal(`arn:aws:logs:${awsPlugin.options.region}:*:*`); }) ); it('should add custom IAM policy statements', () => { - awsSdk.serverless.service.provider.name = 'aws'; - awsSdk.serverless.service.provider.iamRoleStatements = [ + awsPlugin.serverless.service.provider.name = 'aws'; + awsPlugin.serverless.service.provider.iamRoleStatements = [ { Effect: 'Allow', Action: [ @@ -128,20 +131,20 @@ describe('#configureStack', () => { ]; - return awsSdk.configureStack() + return awsPlugin.configureStack() .then(() => { - expect(awsSdk.serverless.service.provider.compiledCloudFormationTemplate + expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Resources.IamPolicyLambdaExecution.Properties.PolicyDocument.Statement[1] - ).to.deep.equal(awsSdk.serverless.service.provider.iamRoleStatements[0]); + ).to.deep.equal(awsPlugin.serverless.service.provider.iamRoleStatements[0]); }); }); it('should use a custom bucket if specified', () => { const bucketName = 'com.serverless.deploys'; - awsSdk.serverless.service.provider.deploymentBucket = bucketName; + awsPlugin.serverless.service.provider.deploymentBucket = bucketName; - const coreCloudFormationTemplate = awsSdk.serverless.utils.readFileSync( + const coreCloudFormationTemplate = awsPlugin.serverless.utils.readFileSync( path.join( __dirname, '..', @@ -149,44 +152,44 @@ describe('#configureStack', () => { 'core-cloudformation-template.json' ) ); - awsSdk.serverless.service.provider + awsPlugin.serverless.service.provider .compiledCloudFormationTemplate = coreCloudFormationTemplate; sinon - .stub(awsSdk.sdk, 'request') - .returns(BbPromise.resolve({ LocationConstraint: awsSdk.options.region })); + .stub(awsPlugin.aws, 'request') + .returns(BbPromise.resolve({ LocationConstraint: awsPlugin.options.region })); - return awsSdk.configureStack() + return awsPlugin.configureStack() .then(() => { expect( - awsSdk.serverless.service.provider.compiledCloudFormationTemplate + awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Outputs.ServerlessDeploymentBucketName.Value ).to.equal(bucketName); // eslint-disable-next-line no-unused-expressions expect( - awsSdk.serverless.service.provider.compiledCloudFormationTemplate + awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Resources.ServerlessDeploymentBucket ).to.not.exist; }); }); it('should not add IamPolicyLambdaExecution', () => { - awsSdk.serverless.service.provider.iamRoleARN = 'some:aws:arn:xxx:*:*'; + awsPlugin.serverless.service.provider.iamRoleARN = 'some:aws:arn:xxx:*:*'; - return awsSdk.configureStack() + return awsPlugin.configureStack() .then(() => expect( - awsSdk.serverless.service.provider.compiledCloudFormationTemplate + awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Resources.IamPolicyLambdaExecution ).to.not.exist); }); it('should not add IamRole', () => { - awsSdk.serverless.service.provider.iamRoleARN = 'some:aws:arn:xxx:*:*'; + awsPlugin.serverless.service.provider.iamRoleARN = 'some:aws:arn:xxx:*:*'; - return awsSdk.configureStack() + return awsPlugin.configureStack() .then(() => expect( - awsSdk.serverless.service.provider.compiledCloudFormationTemplate + awsPlugin.serverless.service.provider.compiledCloudFormationTemplate .Resources.IamRoleLambdaExecution ).to.not.exist); }); diff --git a/lib/plugins/aws/deploy/tests/createStack.js b/lib/plugins/aws/deploy/tests/createStack.js index 51b9d1e27..b821fa793 100644 --- a/lib/plugins/aws/deploy/tests/createStack.js +++ b/lib/plugins/aws/deploy/tests/createStack.js @@ -4,6 +4,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const path = require('path'); const BbPromise = require('bluebird'); +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const testUtils = require('../../../../../tests/utils'); @@ -25,6 +26,7 @@ describe('createStack', () => { beforeEach(() => { const serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); serverless.utils.writeFileSync(serverlessYmlPath, serverlessYml); serverless.config.servicePath = tmpDirPath; const options = { @@ -49,7 +51,7 @@ describe('createStack', () => { .compiledCloudFormationTemplate = coreCloudFormationTemplate; const createStackStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); return awsDeploy.create().then(() => { expect(createStackStub.args[0][0]).to.equal('CloudFormation'); @@ -69,7 +71,7 @@ describe('createStack', () => { awsDeploy.serverless.service.provider.stackTags = { STAGE: 'overridden', tag1: 'value1' }; const createStackStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); return awsDeploy.create().then(() => { expect(createStackStub.args[0][2].Tags) @@ -77,14 +79,14 @@ describe('createStack', () => { { Key: 'STAGE', Value: 'overridden' }, { Key: 'tag1', Value: 'value1' }, ]); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); }); describe('#createStack()', () => { it('should store the core CloudFormation template in the provider object', () => { - sinon.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); const coreCloudFormationTemplate = awsDeploy.serverless.utils.readFileSync( path.join(__dirname, @@ -110,7 +112,7 @@ describe('createStack', () => { const createStub = sinon .stub(awsDeploy, 'create').returns(BbPromise.resolve()); - sinon.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); return awsDeploy.createStack().then(() => { expect(createStub.called).to.be.equal(false); @@ -136,11 +138,11 @@ describe('createStack', () => { const writeCreateTemplateToDiskStub = sinon .stub(awsDeploy, 'writeCreateTemplateToDisk').returns(BbPromise.resolve()); - sinon.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); return awsDeploy.createStack().then((res) => { expect(writeCreateTemplateToDiskStub.calledOnce).to.be.equal(true); - expect(awsDeploy.sdk.request.called).to.be.equal(true); + expect(awsDeploy.aws.request.called).to.be.equal(true); expect(res).to.equal('alreadyCreated'); }); }); @@ -150,7 +152,7 @@ describe('createStack', () => { message: 'Something went wrong.', }; - sinon.stub(awsDeploy.sdk, 'request').returns(BbPromise.reject(errorMock)); + sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.reject(errorMock)); const createStub = sinon .stub(awsDeploy, 'create').returns(BbPromise.resolve()); @@ -167,7 +169,7 @@ describe('createStack', () => { message: 'does not exist', }; - sinon.stub(awsDeploy.sdk, 'request').returns(BbPromise.reject(errorMock)); + sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.reject(errorMock)); const createStub = sinon .stub(awsDeploy, 'create').returns(BbPromise.resolve()); diff --git a/lib/plugins/aws/deploy/tests/setBucketName.js b/lib/plugins/aws/deploy/tests/setBucketName.js index 6652d3497..95e56b321 100644 --- a/lib/plugins/aws/deploy/tests/setBucketName.js +++ b/lib/plugins/aws/deploy/tests/setBucketName.js @@ -2,6 +2,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); @@ -13,6 +14,7 @@ describe('#setBucketName()', () => { beforeEach(() => { serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); const options = { stage: 'dev', region: 'us-east-1', @@ -20,7 +22,7 @@ describe('#setBucketName()', () => { awsDeploy = new AwsDeploy(serverless, options); getServerlessDeploymentBucketNameStub = sinon - .stub(awsDeploy.sdk, 'getServerlessDeploymentBucketName') + .stub(awsDeploy.aws, 'getServerlessDeploymentBucketName') .returns(BbPromise.resolve('bucket-name')); }); @@ -30,7 +32,7 @@ describe('#setBucketName()', () => { expect(getServerlessDeploymentBucketNameStub.calledOnce).to.be.equal(true); expect(getServerlessDeploymentBucketNameStub .calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.getServerlessDeploymentBucketName.restore(); + awsDeploy.aws.getServerlessDeploymentBucketName.restore(); }) ); @@ -39,7 +41,7 @@ describe('#setBucketName()', () => { return awsDeploy.setBucketName().then(() => { expect(getServerlessDeploymentBucketNameStub.calledOnce).to.be.equal(false); - awsDeploy.sdk.getServerlessDeploymentBucketName.restore(); + awsDeploy.aws.getServerlessDeploymentBucketName.restore(); }); }); diff --git a/lib/plugins/aws/deploy/tests/updateStack.js b/lib/plugins/aws/deploy/tests/updateStack.js index 6f0a1aa37..e2d54a532 100644 --- a/lib/plugins/aws/deploy/tests/updateStack.js +++ b/lib/plugins/aws/deploy/tests/updateStack.js @@ -4,6 +4,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const path = require('path'); const BbPromise = require('bluebird'); +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const testUtils = require('../../../../../tests/utils'); @@ -15,6 +16,7 @@ describe('updateStack', () => { beforeEach(() => { serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); const options = { stage: 'dev', region: 'us-east-1', @@ -34,7 +36,7 @@ describe('updateStack', () => { beforeEach(() => { updateStackStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); }); it('should update the stack', () => awsDeploy.update() @@ -51,7 +53,7 @@ describe('updateStack', () => { .to.deep.equal([{ Key: 'STAGE', Value: awsDeploy.options.stage }]); expect(updateStackStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }) ); @@ -74,7 +76,7 @@ describe('updateStack', () => { .to.equal( '{"Statement":[{"Effect":"Allow","Principal":"*","Action":"Update:*","Resource":"*"}]}' ); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/deploy/tests/uploadArtifacts.js b/lib/plugins/aws/deploy/tests/uploadArtifacts.js index 2bd1f70a6..139a432ec 100644 --- a/lib/plugins/aws/deploy/tests/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/tests/uploadArtifacts.js @@ -4,6 +4,7 @@ const sinon = require('sinon'); const path = require('path'); const BbPromise = require('bluebird'); const expect = require('chai').expect; +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const testUtils = require('../../../../../tests/utils'); @@ -14,6 +15,7 @@ describe('uploadArtifacts', () => { beforeEach(() => { serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); const options = { stage: 'dev', region: 'us-east-1', @@ -29,7 +31,7 @@ describe('uploadArtifacts', () => { awsDeploy.serverless.service.provider.compiledCloudFormationTemplate = { key: 'value' }; const putObjectStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); return awsDeploy.uploadCloudFormationFile().then(() => { expect(putObjectStub.calledOnce).to.be.equal(true); @@ -44,19 +46,19 @@ describe('uploadArtifacts', () => { .provider.compiledCloudFormationTemplate)); expect(putObjectStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); }); describe('#uploadZipFile()', () => { it('should throw for null artifact paths', () => { - sinon.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); expect(() => awsDeploy.uploadZipFile(null)).to.throw(Error); }); it('should throw for empty artifact paths', () => { - sinon.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); expect(() => awsDeploy.uploadZipFile('')).to.throw(Error); }); @@ -68,7 +70,7 @@ describe('uploadArtifacts', () => { const artifactFileBuffer = serverless.utils.readFileSync(artifactFilePath); const putObjectStub = sinon - .stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); return awsDeploy.uploadZipFile(artifactFilePath).then(() => { expect(putObjectStub.calledOnce).to.be.equal(true); @@ -82,7 +84,7 @@ describe('uploadArtifacts', () => { .to.be.equal(artifactFileBuffer.toString()); expect(putObjectStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.sdk.request.restore(); + awsDeploy.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/deployFunction/index.js b/lib/plugins/aws/deployFunction/index.js index 770ce3cf7..f2b166917 100644 --- a/lib/plugins/aws/deployFunction/index.js +++ b/lib/plugins/aws/deployFunction/index.js @@ -2,7 +2,6 @@ const BbPromise = require('bluebird'); const fs = require('fs'); -const SDK = require('../'); const validate = require('../lib/validate'); // The Package plugin which is used to zip the service @@ -13,7 +12,7 @@ class AwsDeployFunction { this.serverless = serverless; this.options = options || {}; this.provider = 'aws'; - this.sdk = new SDK(serverless); + this.aws = this.serverless.getProvider(this.provider); this.pkg = new Package(this.serverless, this.options); @@ -38,7 +37,7 @@ class AwsDeployFunction { FunctionName: this.options.functionObj.name, }; - this.sdk.request( + this.aws.request( 'Lambda', 'getFunction', params, @@ -69,7 +68,7 @@ class AwsDeployFunction { ZipFile: data, }; - return this.sdk.request( + return this.aws.request( 'Lambda', 'updateFunctionCode', params, diff --git a/lib/plugins/aws/deployFunction/tests/index.js b/lib/plugins/aws/deployFunction/tests/index.js index 89d42de5a..9887db139 100644 --- a/lib/plugins/aws/deployFunction/tests/index.js +++ b/lib/plugins/aws/deployFunction/tests/index.js @@ -5,7 +5,8 @@ const sinon = require('sinon'); const path = require('path'); const fs = require('fs'); const Package = require('../../../package'); -const AwsDeployFunction = require('../'); +const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsDeployFunction = require('../index'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); const testUtils = require('../../../../../tests/utils'); @@ -44,6 +45,7 @@ describe('AwsDeployFunction', () => { }, }; serverless.init(); + serverless.setProvider('aws', new AwsProvider(serverless)); awsDeployFunction = new AwsDeployFunction(serverless, options); }); @@ -60,6 +62,8 @@ describe('AwsDeployFunction', () => { }); it('should run promise chain in order', () => { + const validateStub = sinon + .stub(awsDeployFunction, 'validate').returns(BbPromise.resolve()); const checkIfFunctionExistsStub = sinon .stub(awsDeployFunction, 'checkIfFunctionExists').returns(BbPromise.resolve()); const zipFunctionStub = sinon @@ -70,13 +74,15 @@ describe('AwsDeployFunction', () => { .stub(awsDeployFunction, 'cleanup').returns(BbPromise.resolve()); return awsDeployFunction.hooks['deploy:function:deploy']().then(() => { - expect(checkIfFunctionExistsStub.calledOnce).to.be.equal(true); + expect(validateStub.calledOnce).to.equal(true); + expect(checkIfFunctionExistsStub.calledAfter(validateStub)) + .to.equal(true); expect(zipFunctionStub.calledAfter(checkIfFunctionExistsStub)) - .to.be.equal(true); + .to.equal(true); expect(deployFunctionStub.calledAfter(zipFunctionStub)) - .to.be.equal(true); + .to.equal(true); expect(cleanupStub.calledAfter(deployFunctionStub)) - .to.be.equal(true); + .to.equal(true); awsDeployFunction.checkIfFunctionExists.restore(); awsDeployFunction.zipFunction.restore(); @@ -94,7 +100,7 @@ describe('AwsDeployFunction', () => { it('should check if the function is deployed', () => { const getFunctionStub = sinon - .stub(awsDeployFunction.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsDeployFunction.aws, 'request').returns(BbPromise.resolve()); awsDeployFunction.serverless.service.functions = { first: { @@ -111,7 +117,7 @@ describe('AwsDeployFunction', () => { expect(getFunctionStub.args[0][0]).to.be.equal('Lambda'); expect(getFunctionStub.args[0][1]).to.be.equal('getFunction'); expect(getFunctionStub.args[0][2].FunctionName).to.be.equal('first'); - awsDeployFunction.sdk.request.restore(); + awsDeployFunction.aws.request.restore(); }); }); }); @@ -145,7 +151,7 @@ describe('AwsDeployFunction', () => { awsDeployFunction.options.functionObj.artifact = artifactFilePath; const updateFunctionCodeStub = sinon - .stub(awsDeployFunction.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsDeployFunction.aws, 'request').returns(BbPromise.resolve()); return awsDeployFunction.deployFunction().then(() => { const data = fs.readFileSync(artifactFilePath); @@ -158,7 +164,7 @@ describe('AwsDeployFunction', () => { expect(updateFunctionCodeStub.args[0][1]).to.be.equal('updateFunctionCode'); expect(updateFunctionCodeStub.args[0][2].FunctionName).to.be.equal('first'); expect(updateFunctionCodeStub.args[0][2].ZipFile).to.deep.equal(data); - awsDeployFunction.sdk.request.restore(); + awsDeployFunction.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/info/index.js b/lib/plugins/aws/info/index.js index ab0213c81..336313241 100644 --- a/lib/plugins/aws/info/index.js +++ b/lib/plugins/aws/info/index.js @@ -2,16 +2,15 @@ const BbPromise = require('bluebird'); const validate = require('../lib/validate'); -const SDK = require('../'); const chalk = require('chalk'); const _ = require('lodash'); class AwsInfo { constructor(serverless, options) { this.serverless = serverless; - this.options = options || {}; this.provider = 'aws'; - this.sdk = new SDK(serverless); + this.aws = this.serverless.getProvider(this.provider); + this.options = options || {}; Object.assign(this, validate); this.hooks = { @@ -37,7 +36,7 @@ class AwsInfo { * Gather information about the service */ gather() { - const stackName = this.sdk.getStackName(this.options.stage); + const stackName = this.aws.getStackName(this.options.stage); const info = { service: this.serverless.service.service, stage: this.options.stage, @@ -45,7 +44,7 @@ class AwsInfo { }; // Get info from CloudFormation Outputs - return this.sdk.request('CloudFormation', + return this.aws.request('CloudFormation', 'describeStacks', { StackName: stackName }, this.options.stage, @@ -113,7 +112,7 @@ class AwsInfo { const apiKeyNames = this.serverless.service.provider.apiKeys || []; if (apiKeyNames.length) { - return this.sdk.request('APIGateway', + return this.aws.request('APIGateway', 'getApiKeys', { includeValues: true }, this.options.stage, diff --git a/lib/plugins/aws/info/tests/index.js b/lib/plugins/aws/info/tests/index.js index 3481b1450..94755fcb5 100644 --- a/lib/plugins/aws/info/tests/index.js +++ b/lib/plugins/aws/info/tests/index.js @@ -3,6 +3,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const AwsInfo = require('../'); +const AwsProvider = require('../../../awsProvider/awsProvider'); const Serverless = require('../../../../Serverless'); const CLI = require('../../../../classes/CLI'); const BbPromise = require('bluebird'); @@ -10,6 +11,7 @@ const chalk = require('chalk'); describe('AwsInfo', () => { const serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); serverless.service.functions = { function1: { events: [ @@ -158,7 +160,7 @@ describe('AwsInfo', () => { ], }; - const describeStackStub = sinon.stub(awsInfo.sdk, 'request') + const describeStackStub = sinon.stub(awsInfo.aws, 'request') .returns(BbPromise.resolve(describeStacksResponse)); it('should gather with correct params', () => awsInfo.gather() @@ -167,7 +169,7 @@ describe('AwsInfo', () => { expect(describeStackStub.args[0][0]).to.equal('CloudFormation'); expect(describeStackStub.args[0][1]).to.equal('describeStacks'); expect(describeStackStub.args[0][2].StackName) - .to.equal(awsInfo.sdk.getStackName(awsInfo.options.stage)); + .to.equal(awsInfo.aws.getStackName(awsInfo.options.stage)); expect(describeStackStub .calledWith(awsInfo.options.stage, awsInfo.options.region)); }) @@ -219,7 +221,7 @@ describe('AwsInfo', () => { }); it("should provide only general info when stack doesn't exist (ValidationError)", () => { - awsInfo.sdk.request.restore(); + awsInfo.aws.request.restore(); serverless.service.service = 'my-first'; const validationError = { @@ -227,7 +229,7 @@ describe('AwsInfo', () => { message: 'Stack with id not-created-service does not exist', }; - sinon.stub(awsInfo.sdk, 'request').returns(BbPromise.reject(validationError)); + sinon.stub(awsInfo.aws, 'request').returns(BbPromise.reject(validationError)); const expectedInfo = { service: 'my-first', @@ -241,8 +243,8 @@ describe('AwsInfo', () => { }); it('should throw a ServerlessError when AWS sdk throws an error', () => { - awsInfo.sdk.request.restore(); - sinon.stub(awsInfo.sdk, 'request').returns(BbPromise.reject(Error)); + awsInfo.aws.request.restore(); + sinon.stub(awsInfo.aws, 'request').returns(BbPromise.reject(Error)); return awsInfo.gather().catch((e) => { expect(e.name).to.equal('ServerlessError'); @@ -253,7 +255,7 @@ describe('AwsInfo', () => { describe('#getApiKeyValues()', () => { it('should return the api keys in the info object', () => { // TODO: implement a pattern for stub restoring to get rid of this - awsInfo.sdk.request.restore(); + awsInfo.aws.request.restore(); // set the API Keys for the service awsInfo.serverless.service.provider.apiKeys = ['foo', 'bar']; @@ -295,14 +297,14 @@ describe('AwsInfo', () => { }; const getApiKeysStub = sinon - .stub(awsInfo.sdk, 'request') + .stub(awsInfo.aws, 'request') .returns(BbPromise.resolve(apiKeyItems)); return awsInfo.getApiKeyValues(gatheredData).then((result) => { expect(getApiKeysStub.calledOnce).to.equal(true); expect(result.info.apiKeys).to.deep.equal(gatheredDataAfterKeyLookup.info.apiKeys); - awsInfo.sdk.request.restore(); + awsInfo.aws.request.restore(); }); }); @@ -317,14 +319,14 @@ describe('AwsInfo', () => { }; const getApiKeysStub = sinon - .stub(awsInfo.sdk, 'request') + .stub(awsInfo.aws, 'request') .returns(BbPromise.resolve()); return awsInfo.getApiKeyValues(gatheredData).then((result) => { expect(getApiKeysStub.calledOnce).to.equal(false); expect(result).to.deep.equal(gatheredData); - awsInfo.sdk.request.restore(); + awsInfo.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/invoke/index.js b/lib/plugins/aws/invoke/index.js index 3782cdbe9..a39b97fe9 100644 --- a/lib/plugins/aws/invoke/index.js +++ b/lib/plugins/aws/invoke/index.js @@ -3,7 +3,6 @@ const BbPromise = require('bluebird'); const chalk = require('chalk'); const path = require('path'); -const SDK = require('../'); const moment = require('moment'); const validate = require('../lib/validate'); @@ -12,7 +11,7 @@ class AwsInvoke { this.serverless = serverless; this.options = options || {}; this.provider = 'aws'; - this.sdk = new SDK(serverless); + this.aws = this.serverless.getProvider(this.provider); Object.assign(this, validate); @@ -58,7 +57,7 @@ class AwsInvoke { Payload: new Buffer(JSON.stringify(this.options.data || {})), }; - return this.sdk.request('Lambda', 'invoke', params, this.options.stage, this.options.region); + return this.aws.request('Lambda', 'invoke', params, this.options.stage, this.options.region); } log(invocationReply) { diff --git a/lib/plugins/aws/invoke/tests/index.js b/lib/plugins/aws/invoke/tests/index.js index 0229844c8..7ec519f92 100644 --- a/lib/plugins/aws/invoke/tests/index.js +++ b/lib/plugins/aws/invoke/tests/index.js @@ -4,12 +4,14 @@ const expect = require('chai').expect; const sinon = require('sinon'); const path = require('path'); const AwsInvoke = require('../'); +const AwsProvider = require('../../../awsProvider/awsProvider'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); const testUtils = require('../../../../../tests/utils'); describe('AwsInvoke', () => { const serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); const options = { stage: 'dev', region: 'us-east-1', @@ -136,7 +138,7 @@ describe('AwsInvoke', () => { describe('#invoke()', () => { let invokeStub; beforeEach(() => { - invokeStub = sinon.stub(awsInvoke.sdk, 'request').returns(BbPromise.resolve()); + invokeStub = sinon.stub(awsInvoke.aws, 'request').returns(BbPromise.resolve()); awsInvoke.serverless.service.service = 'new-service'; awsInvoke.options = { stage: 'dev', @@ -155,7 +157,7 @@ describe('AwsInvoke', () => { expect(invokeStub.args[0][2].InvocationType).to.be.equal('RequestResponse'); expect(invokeStub.args[0][2].LogType).to.be.equal('None'); expect(typeof invokeStub.args[0][2].Payload).to.not.be.equal('undefined'); - awsInvoke.sdk.request.restore(); + awsInvoke.aws.request.restore(); }) ); @@ -169,7 +171,7 @@ describe('AwsInvoke', () => { expect(invokeStub.args[0][2].InvocationType).to.be.equal('RequestResponse'); expect(invokeStub.args[0][2].LogType).to.be.equal('Tail'); expect(typeof invokeStub.args[0][2].Payload).to.not.be.equal('undefined'); - awsInvoke.sdk.request.restore(); + awsInvoke.aws.request.restore(); }); }); @@ -183,7 +185,7 @@ describe('AwsInvoke', () => { expect(invokeStub.args[0][2].InvocationType).to.be.equal('OtherType'); expect(invokeStub.args[0][2].LogType).to.be.equal('None'); expect(typeof invokeStub.args[0][2].Payload).to.not.be.equal('undefined'); - awsInvoke.sdk.request.restore(); + awsInvoke.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/lib/monitorStack.js b/lib/plugins/aws/lib/monitorStack.js index d17f363b9..2ef93e6db 100644 --- a/lib/plugins/aws/lib/monitorStack.js +++ b/lib/plugins/aws/lib/monitorStack.js @@ -35,7 +35,7 @@ module.exports = { const params = { StackName: cfData.StackId, }; - return this.sdk.request('CloudFormation', + return this.aws.request('CloudFormation', 'describeStackEvents', params, this.options.stage, diff --git a/lib/plugins/aws/logs/index.js b/lib/plugins/aws/logs/index.js index 03174be5d..750c3b490 100644 --- a/lib/plugins/aws/logs/index.js +++ b/lib/plugins/aws/logs/index.js @@ -3,7 +3,6 @@ const BbPromise = require('bluebird'); const chalk = require('chalk'); const _ = require('lodash'); -const SDK = require('../'); const os = require('os'); const moment = require('moment'); const validate = require('../lib/validate'); @@ -13,7 +12,7 @@ class AwsLogs { this.serverless = serverless; this.options = options || {}; this.provider = 'aws'; - this.sdk = new SDK(serverless); + this.aws = this.serverless.getProvider(this.provider); Object.assign(this, validate); @@ -45,7 +44,7 @@ class AwsLogs { orderBy: 'LastEventTime', }; - return this.sdk + return this.aws .request('CloudWatchLogs', 'describeLogStreams', params, @@ -120,7 +119,7 @@ class AwsLogs { } } - return this.sdk + return this.aws .request('CloudWatchLogs', 'filterLogEvents', params, diff --git a/lib/plugins/aws/logs/tests/index.js b/lib/plugins/aws/logs/tests/index.js index 09e1723ce..651ca6c7c 100644 --- a/lib/plugins/aws/logs/tests/index.js +++ b/lib/plugins/aws/logs/tests/index.js @@ -2,6 +2,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsLogs = require('../'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); @@ -17,6 +18,7 @@ describe('AwsLogs', () => { function: 'first', }; serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); awsLogs = new AwsLogs(serverless, options); }); @@ -114,7 +116,7 @@ describe('AwsLogs', () => { }, ], }; - const getLogStreamsStub = sinon.stub(awsLogs.sdk, 'request').returns( + const getLogStreamsStub = sinon.stub(awsLogs.aws, 'request').returns( BbPromise.resolve(replyMock) ); @@ -137,20 +139,20 @@ describe('AwsLogs', () => { expect(logStreamNames[1]) .to.be.equal('2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba'); - awsLogs.sdk.request.restore(); + awsLogs.aws.request.restore(); }); }); it('should throw error if no log streams found', () => { - sinon.stub(awsLogs.sdk, 'request').returns(BbPromise.resolve()); + sinon.stub(awsLogs.aws, 'request').returns(BbPromise.resolve()); return awsLogs.getLogStreams() .then(() => { expect(1).to.equal(2); - awsLogs.sdk.request.restore(); + awsLogs.aws.request.restore(); }).catch(e => { expect(e.name).to.be.equal('ServerlessError'); - awsLogs.sdk.request.restore(); + awsLogs.aws.request.restore(); }); }); }); @@ -175,7 +177,7 @@ describe('AwsLogs', () => { '2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba', '2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba', ]; - const filterLogEventsStub = sinon.stub(awsLogs.sdk, 'request').returns( + const filterLogEventsStub = sinon.stub(awsLogs.aws, 'request').returns( BbPromise.resolve(replyMock) ); awsLogs.serverless.service.service = 'new-service'; @@ -201,7 +203,7 @@ describe('AwsLogs', () => { expect(filterLogEventsStub.args[0][2].logStreamNames).to.deep.equal(logStreamNamesMock); expect(filterLogEventsStub.args[0][2].filterPattern).to.be.equal('error'); expect(typeof filterLogEventsStub.args[0][2].startTime).to.be.equal('number'); - awsLogs.sdk.request.restore(); + awsLogs.aws.request.restore(); }); }); @@ -224,7 +226,7 @@ describe('AwsLogs', () => { '2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba', '2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba', ]; - const filterLogEventsStub = sinon.stub(awsLogs.sdk, 'request').returns( + const filterLogEventsStub = sinon.stub(awsLogs.aws, 'request').returns( BbPromise.resolve(replyMock) ); awsLogs.serverless.service.service = 'new-service'; @@ -250,7 +252,7 @@ describe('AwsLogs', () => { expect(filterLogEventsStub.args[0][2].logStreamNames).to.deep.equal(logStreamNamesMock); expect(filterLogEventsStub.args[0][2].filterPattern).to.be.equal('error'); expect(typeof filterLogEventsStub.args[0][2].startTime).to.be.equal('number'); - awsLogs.sdk.request.restore(); + awsLogs.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/remove/index.js b/lib/plugins/aws/remove/index.js index 90d1149c6..a7aa02005 100644 --- a/lib/plugins/aws/remove/index.js +++ b/lib/plugins/aws/remove/index.js @@ -6,14 +6,12 @@ const monitorStack = require('../lib/monitorStack'); const emptyS3Bucket = require('./lib/bucket'); const removeStack = require('./lib/stack'); -const SDK = require('../'); - class AwsRemove { constructor(serverless, options) { this.serverless = serverless; this.options = options || {}; this.provider = 'aws'; - this.sdk = new SDK(serverless); + this.aws = this.serverless.getProvider(this.provider); Object.assign(this, validate, emptyS3Bucket, removeStack, monitorStack); diff --git a/lib/plugins/aws/remove/lib/bucket.js b/lib/plugins/aws/remove/lib/bucket.js index b0037c9e0..e96b41dae 100644 --- a/lib/plugins/aws/remove/lib/bucket.js +++ b/lib/plugins/aws/remove/lib/bucket.js @@ -4,7 +4,7 @@ const BbPromise = require('bluebird'); module.exports = { setServerlessDeploymentBucketName() { - return this.sdk.getServerlessDeploymentBucketName(this.options.stage, this.options.region) + return this.aws.getServerlessDeploymentBucketName(this.options.stage, this.options.region) .then((bucketName) => { this.bucketName = bucketName; }); @@ -15,7 +15,7 @@ module.exports = { this.serverless.cli.log('Getting all objects in S3 bucket...'); const serviceStage = `${this.serverless.service.service}/${this.options.stage}`; - return this.sdk.request('S3', 'listObjectsV2', { + return this.aws.request('S3', 'listObjectsV2', { Bucket: this.bucketName, Prefix: `serverless/${serviceStage}`, }, this.options.stage, this.options.region).then((result) => { @@ -33,7 +33,7 @@ module.exports = { deleteObjects() { this.serverless.cli.log('Removing objects in S3 bucket...'); if (this.objectsInBucket.length) { - return this.sdk.request('S3', 'deleteObjects', { + return this.aws.request('S3', 'deleteObjects', { Bucket: this.bucketName, Delete: { Objects: this.objectsInBucket, diff --git a/lib/plugins/aws/remove/lib/stack.js b/lib/plugins/aws/remove/lib/stack.js index fafe95e0a..a6c151c9f 100644 --- a/lib/plugins/aws/remove/lib/stack.js +++ b/lib/plugins/aws/remove/lib/stack.js @@ -13,7 +13,7 @@ module.exports = { StackId: stackName, }; - return this.sdk.request('CloudFormation', + return this.aws.request('CloudFormation', 'deleteStack', params, this.options.stage, diff --git a/lib/plugins/aws/remove/tests/bucket.js b/lib/plugins/aws/remove/tests/bucket.js index 4ff8de3f1..2423f4943 100644 --- a/lib/plugins/aws/remove/tests/bucket.js +++ b/lib/plugins/aws/remove/tests/bucket.js @@ -2,12 +2,14 @@ const expect = require('chai').expect; const sinon = require('sinon'); +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsRemove = require('../index'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); describe('emptyS3Bucket', () => { const serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); let awsRemove; @@ -23,7 +25,7 @@ describe('emptyS3Bucket', () => { describe('#setServerlessDeploymentBucketName()', () => { it('should store the name of the Serverless deployment bucket in the "this" variable', () => { const getServerlessDeploymentBucketNameStub = sinon - .stub(awsRemove.sdk, 'getServerlessDeploymentBucketName') + .stub(awsRemove.aws, 'getServerlessDeploymentBucketName') .returns(BbPromise.resolve('new-service-dev-us-east-1-12345678')); return awsRemove.setServerlessDeploymentBucketName().then(() => { @@ -31,14 +33,14 @@ describe('emptyS3Bucket', () => { expect(getServerlessDeploymentBucketNameStub.calledOnce).to.be.equal(true); expect(getServerlessDeploymentBucketNameStub .calledWith(awsRemove.options.stage, awsRemove.options.region)); - awsRemove.sdk.getServerlessDeploymentBucketName.restore(); + awsRemove.aws.getServerlessDeploymentBucketName.restore(); }); }); }); describe('#listObjects()', () => { it('should resolve if no objects are present', () => { - const listObjectsStub = sinon.stub(awsRemove.sdk, 'request') + const listObjectsStub = sinon.stub(awsRemove.aws, 'request') .returns(BbPromise.resolve()); return awsRemove.listObjects().then(() => { @@ -49,12 +51,12 @@ describe('emptyS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket) .to.be.equal(awsRemove.bucketName); expect(awsRemove.objectsInBucket.length).to.equal(0); - awsRemove.sdk.request.restore(); + awsRemove.aws.request.restore(); }); }); it('should push objects to the array if present', () => { - const listObjectsStub = sinon.stub(awsRemove.sdk, 'request') + const listObjectsStub = sinon.stub(awsRemove.aws, 'request') .returns(BbPromise.resolve({ Contents: [ { Key: 'object1' }, @@ -71,7 +73,7 @@ describe('emptyS3Bucket', () => { .to.be.equal(awsRemove.bucketName); expect(awsRemove.objectsInBucket[0]).to.deep.equal({ Key: 'object1' }); expect(awsRemove.objectsInBucket[1]).to.deep.equal({ Key: 'object2' }); - awsRemove.sdk.request.restore(); + awsRemove.aws.request.restore(); }); }); }); @@ -80,7 +82,7 @@ describe('emptyS3Bucket', () => { it('should delete all objects in the S3 bucket', () => { awsRemove.objectsInBucket = [{ Key: 'foo' }]; - const deleteObjectsStub = sinon.stub(awsRemove.sdk, 'request') + const deleteObjectsStub = sinon.stub(awsRemove.aws, 'request') .returns(BbPromise.resolve()); return awsRemove.deleteObjects().then(() => { @@ -90,7 +92,7 @@ describe('emptyS3Bucket', () => { .to.be.equal(awsRemove.bucketName); expect(deleteObjectsStub.args[0][2].Delete.Objects) .to.be.equal(awsRemove.objectsInBucket); - awsRemove.sdk.request.restore(); + awsRemove.aws.request.restore(); }); }); diff --git a/lib/plugins/aws/remove/tests/stack.js b/lib/plugins/aws/remove/tests/stack.js index d703edead..996352cd2 100644 --- a/lib/plugins/aws/remove/tests/stack.js +++ b/lib/plugins/aws/remove/tests/stack.js @@ -2,12 +2,14 @@ const expect = require('chai').expect; const sinon = require('sinon'); +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsRemove = require('../index'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); describe('removeStack', () => { const serverless = new Serverless(); + serverless.setProvider('aws', new AwsProvider(serverless)); let awsRemove; @@ -23,12 +25,12 @@ describe('removeStack', () => { describe('#remove()', () => { it('should remove a stack', () => { const removeStackStub = sinon - .stub(awsRemove.sdk, 'request').returns(BbPromise.resolve()); + .stub(awsRemove.aws, 'request').returns(BbPromise.resolve()); return awsRemove.remove().then(() => { expect(removeStackStub.calledOnce).to.be.equal(true); expect(removeStackStub.calledWith(awsRemove.options.stage, awsRemove.options.region)); - awsRemove.sdk.request.restore(); + awsRemove.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/tests/monitorStack.js b/lib/plugins/aws/tests/monitorStack.js index d07ebf812..2c6e2fcbf 100644 --- a/lib/plugins/aws/tests/monitorStack.js +++ b/lib/plugins/aws/tests/monitorStack.js @@ -4,7 +4,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const BbPromise = require('bluebird'); const Serverless = require('../../../Serverless'); -const SDK = require('../index'); +const AwsProvider = require('../../awsProvider/awsProvider'); const CLI = require('../../../classes/CLI'); const monitorStack = require('../lib/monitorStack'); @@ -14,7 +14,7 @@ describe('monitorStack', () => { beforeEach(() => { awsPlugin.serverless = serverless; - awsPlugin.sdk = new SDK(serverless); + awsPlugin.aws = new AwsProvider(serverless); awsPlugin.serverless.cli = new CLI(serverless); awsPlugin.options = { stage: 'dev', @@ -27,28 +27,28 @@ describe('monitorStack', () => { describe('#monitorStack()', () => { it('should skip monitoring if the --noDeploy option is specified', () => { awsPlugin.options.noDeploy = true; - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; return awsPlugin.monitorStack('update', cfDataMock, 10).then(() => { expect(describeStackEventsStub.callCount).to.be.equal(0); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); it('should skip monitoring if the stack was already created', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); return awsPlugin.monitorStack('update', 'alreadyCreated', 10).then(() => { expect(describeStackEventsStub.callCount).to.be.equal(0); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); it('should keep monitoring until CREATE_COMPLETE stack status', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -87,12 +87,12 @@ describe('monitorStack', () => { awsPlugin.options.region )); expect(stackStatus).to.be.equal('CREATE_COMPLETE'); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); it('should keep monitoring until UPDATE_COMPLETE stack status', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -131,12 +131,12 @@ describe('monitorStack', () => { awsPlugin.options.region )); expect(stackStatus).to.be.equal('UPDATE_COMPLETE'); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); it('should keep monitoring until DELETE_COMPLETE stack status', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -175,12 +175,12 @@ describe('monitorStack', () => { awsPlugin.options.region )); expect(stackStatus).to.be.equal('DELETE_COMPLETE'); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); it('should keep monitoring until DELETE_COMPLETE or stack not found catch', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -211,13 +211,13 @@ describe('monitorStack', () => { awsPlugin.options.region )); expect(stackStatus).to.be.equal('DELETE_COMPLETE'); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); it('should output all stack events information with the --verbose option', () => { awsPlugin.options.verbose = true; - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -283,12 +283,12 @@ describe('monitorStack', () => { awsPlugin.options.stage, awsPlugin.options.region )); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); it('should catch describeStackEvents error if stack was not in deleting state', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -307,12 +307,12 @@ describe('monitorStack', () => { awsPlugin.options.stage, awsPlugin.options.region )); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); it('should throw an error and exit immediataley if statck status is *_FAILED', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -380,7 +380,7 @@ describe('monitorStack', () => { awsPlugin.options.stage, awsPlugin.options.region )); - awsPlugin.sdk.request.restore(); + awsPlugin.aws.request.restore(); }); }); }); diff --git a/lib/plugins/aws/index.js b/lib/plugins/awsProvider/awsProvider.js similarity index 98% rename from lib/plugins/aws/index.js rename to lib/plugins/awsProvider/awsProvider.js index c3eb9ca80..6e4817877 100644 --- a/lib/plugins/aws/index.js +++ b/lib/plugins/awsProvider/awsProvider.js @@ -70,11 +70,12 @@ const impl = { }, }; -class SDK { +class AwsProvider { constructor(serverless) { - // Defaults - this.sdk = AWS; this.serverless = serverless; + this.sdk = AWS; + + this.serverless.setProvider('aws', this); // Use HTTPS Proxy (Optional) const proxy = process.env.proxy @@ -187,4 +188,4 @@ class SDK { } } -module.exports = SDK; +module.exports = AwsProvider; diff --git a/lib/plugins/aws/tests/index.js b/lib/plugins/awsProvider/awsProvider.test.js similarity index 78% rename from lib/plugins/aws/tests/index.js rename to lib/plugins/awsProvider/awsProvider.test.js index 553d097cf..0bf646ae4 100644 --- a/lib/plugins/aws/tests/index.js +++ b/lib/plugins/awsProvider/awsProvider.test.js @@ -3,12 +3,12 @@ const sinon = require('sinon'); const BbPromise = require('bluebird'); const expect = require('chai').expect; -const Serverless = require('../../../Serverless'); -const AwsSdk = require('../'); +const Serverless = require('../../Serverless'); +const AwsProvider = require('./awsProvider'); const proxyquire = require('proxyquire'); -describe('AWS SDK', () => { - let awsSdk; +describe('AwsProvider', () => { + let awsProvider; let serverless; beforeEach(() => { @@ -17,24 +17,24 @@ describe('AWS SDK', () => { region: 'us-east-1', }; serverless = new Serverless(options); - awsSdk = new AwsSdk(serverless, options); - awsSdk.serverless.cli = new serverless.classes.CLI(); + awsProvider = new AwsProvider(serverless, options); + awsProvider.serverless.cli = new serverless.classes.CLI(); }); describe('#constructor()', () => { it('should set AWS instance', () => { - expect(typeof awsSdk.sdk).to.not.equal('undefined'); + expect(typeof awsProvider.sdk).to.not.equal('undefined'); }); it('should set Serverless instance', () => { - expect(typeof awsSdk.serverless).to.not.equal('undefined'); + expect(typeof awsProvider.serverless).to.not.equal('undefined'); }); it('should set AWS proxy', () => { process.env.proxy = 'http://a.b.c.d:n'; - const newAwsSdk = new AwsSdk(serverless); + const newAwsProvider = new AwsProvider(serverless); - expect(typeof newAwsSdk.sdk.config.httpOptions.agent).to.not.equal('undefined'); + expect(typeof newAwsProvider.sdk.config.httpOptions.agent).to.not.equal('undefined'); // clear env delete process.env.proxy; @@ -42,9 +42,9 @@ describe('AWS SDK', () => { it('should set AWS timeout', () => { process.env.AWS_CLIENT_TIMEOUT = '120000'; - const newAwsSdk = new AwsSdk(serverless); + const newAwsProvider = new AwsProvider(serverless); - expect(typeof newAwsSdk.sdk.config.httpOptions.timeout).to.not.equal('undefined'); + expect(typeof newAwsProvider.sdk.config.httpOptions.timeout).to.not.equal('undefined'); // clear env delete process.env.AWS_CLIENT_TIMEOUT; @@ -65,10 +65,10 @@ describe('AWS SDK', () => { }; } } - awsSdk.sdk = { + awsProvider.sdk = { S3: FakeS3, }; - awsSdk.serverless.service.environment = { + awsProvider.serverless.service.environment = { vars: {}, stages: { dev: { @@ -80,7 +80,7 @@ describe('AWS SDK', () => { }, }; - return awsSdk.request('S3', 'putObject', {}, 'dev', 'us-east-1').then(data => { + return awsProvider.request('S3', 'putObject', {}, 'dev', 'us-east-1').then(data => { expect(data.called).to.equal(true); }); }); @@ -110,10 +110,10 @@ describe('AWS SDK', () => { }; } } - awsSdk.sdk = { + awsProvider.sdk = { S3: FakeS3, }; - awsSdk.request('S3', 'error', {}, 'dev', 'us-east-1') + awsProvider.request('S3', 'error', {}, 'dev', 'us-east-1') .then(data => { // eslint-disable-next-line no-unused-expressions expect(data).to.exist; @@ -142,10 +142,10 @@ describe('AWS SDK', () => { }; } } - awsSdk.sdk = { + awsProvider.sdk = { S3: FakeS3, }; - awsSdk.request('S3', 'error', {}, 'dev', 'us-east-1') + awsProvider.request('S3', 'error', {}, 'dev', 'us-east-1') .then(() => done('Should not succeed')) .catch(() => done()); }); @@ -168,10 +168,10 @@ describe('AWS SDK', () => { }; } } - awsSdk.sdk = { + awsProvider.sdk = { S3: FakeS3, }; - awsSdk.request('S3', 'error', {}, 'dev', 'us-east-1') + awsProvider.request('S3', 'error', {}, 'dev', 'us-east-1') .then(() => done('Should not succeed')) .catch((err) => { expect(err.message).to.contain('https://git.io/viZAC'); @@ -188,36 +188,36 @@ describe('AWS SDK', () => { return config; }; const awsStub = sinon.stub().returns(); - const AwsSdkProxyquired = proxyquire('../index.js', { + const AwsProviderProxyquired = proxyquire('./awsProvider.js', { 'aws-sdk': awsStub, }); - let newAwsSdk; + let newAwsProvider; beforeEach(() => { - newAwsSdk = new AwsSdkProxyquired(serverless); + newAwsProvider = new AwsProviderProxyquired(serverless); }); it('should set region for credentials', () => { - const credentials = newAwsSdk.getCredentials('teststage', 'testregion'); + const credentials = newAwsProvider.getCredentials('teststage', 'testregion'); expect(credentials.region).to.equal('testregion'); }); it('should get credentials from provider', () => { serverless.service.provider.profile = 'notDefault'; - const credentials = newAwsSdk.getCredentials(); + const credentials = newAwsProvider.getCredentials(); expect(credentials.credentials.profile).to.equal('notDefault'); }); it('should not set credentials if empty profile is set', () => { serverless.service.provider.profile = ''; - const credentials = mockCreds(newAwsSdk.getCredentials('teststage', 'testregion')); + const credentials = mockCreds(newAwsProvider.getCredentials('teststage', 'testregion')); expect(credentials).to.eql({ region: 'testregion' }); }); it('should not set credentials if credentials is an empty object', () => { serverless.service.provider.credentials = {}; - const credentials = mockCreds(newAwsSdk.getCredentials('teststage', 'testregion')); + const credentials = mockCreds(newAwsProvider.getCredentials('teststage', 'testregion')); expect(credentials).to.eql({ region: 'testregion' }); }); @@ -227,7 +227,7 @@ describe('AWS SDK', () => { secretAccessKey: undefined, sessionToken: undefined, }; - const credentials = mockCreds(newAwsSdk.getCredentials('teststage', 'testregion')); + const credentials = mockCreds(newAwsProvider.getCredentials('teststage', 'testregion')); expect(credentials).to.eql({ region: 'testregion' }); }); @@ -237,7 +237,7 @@ describe('AWS SDK', () => { secretAccessKey: '', sessionToken: '', }; - const credentials = mockCreds(newAwsSdk.getCredentials('teststage', 'testregion')); + const credentials = mockCreds(newAwsProvider.getCredentials('teststage', 'testregion')); expect(credentials).to.eql({ region: 'testregion' }); }); @@ -255,7 +255,7 @@ describe('AWS SDK', () => { secretAccessKey: 'secretAccessKey', sessionToken: 'sessionToken', }; - const credentials = newAwsSdk.getCredentials('teststage', 'testregion'); + const credentials = newAwsProvider.getCredentials('teststage', 'testregion'); expect(credentials.credentials).to.deep.eql(serverless.service.provider.credentials); process.env.AWS_ACCESS_KEY_ID = tmpAccessKeyID; @@ -277,7 +277,7 @@ describe('AWS SDK', () => { process.env.AWS_ACCESS_KEY_ID = testVal.accessKeyId; process.env.AWS_SECRET_ACCESS_KEY = testVal.secretAccessKey; process.env.AWS_SESSION_TOKEN = testVal.sessionToken; - const credentials = newAwsSdk.getCredentials('teststage', 'testregion'); + const credentials = newAwsProvider.getCredentials('teststage', 'testregion'); process.env.AWS_ACCESS_KEY_ID = prevVal.accessKeyId; process.env.AWS_SECRET_ACCESS_KEY = prevVal.secretAccessKey; process.env.AWS_SESSION_TOKEN = prevVal.sessionToken; @@ -298,7 +298,7 @@ describe('AWS SDK', () => { process.env.AWS_TESTSTAGE_ACCESS_KEY_ID = testVal.accessKeyId; process.env.AWS_TESTSTAGE_SECRET_ACCESS_KEY = testVal.secretAccessKey; process.env.AWS_TESTSTAGE_SESSION_TOKEN = testVal.sessionToken; - const credentials = newAwsSdk.getCredentials('teststage', 'testregion'); + const credentials = newAwsProvider.getCredentials('teststage', 'testregion'); process.env.AWS_TESTSTAGE_ACCESS_KEY_ID = prevVal.accessKeyId; process.env.AWS_TESTSTAGE_SECRET_ACCESS_KEY = prevVal.secretAccessKey; process.env.AWS_TESTSTAGE_SESSION_TOKEN = prevVal.sessionToken; @@ -307,26 +307,26 @@ describe('AWS SDK', () => { it('should not set credentials if profile is not set', () => { serverless.service.provider.profile = undefined; - const credentials = mockCreds(newAwsSdk.getCredentials('teststage', 'testregion')); + const credentials = mockCreds(newAwsProvider.getCredentials('teststage', 'testregion')); expect(credentials).to.eql({ region: 'testregion' }); }); it('should not set credentials if empty profile is set', () => { serverless.service.provider.profile = ''; - const credentials = mockCreds(newAwsSdk.getCredentials('teststage', 'testregion')); + const credentials = mockCreds(newAwsProvider.getCredentials('teststage', 'testregion')); expect(credentials).to.eql({ region: 'testregion' }); }); it('should get credentials from provider declared profile', () => { serverless.service.provider.profile = 'notDefault'; - const credentials = newAwsSdk.getCredentials(); + const credentials = newAwsProvider.getCredentials(); expect(credentials.credentials.profile).to.equal('notDefault'); }); it('should get credentials from environment declared for-all-stages profile', () => { const prevVal = process.env.AWS_PROFILE; process.env.AWS_PROFILE = 'notDefault'; - const credentials = newAwsSdk.getCredentials(); + const credentials = newAwsProvider.getCredentials(); process.env.AWS_PROFILE = prevVal; expect(credentials.credentials.profile).to.equal('notDefault'); }); @@ -334,7 +334,7 @@ describe('AWS SDK', () => { it('should get credentials from environment declared stage-specific profile', () => { const prevVal = process.env.AWS_TESTSTAGE_PROFILE; process.env.AWS_TESTSTAGE_PROFILE = 'notDefault'; - const credentials = newAwsSdk.getCredentials('teststage', 'testregion'); + const credentials = newAwsProvider.getCredentials('teststage', 'testregion'); process.env.AWS_TESTSTAGE_PROFILE = prevVal; expect(credentials.credentials.profile).to.equal('notDefault'); }); @@ -348,25 +348,25 @@ describe('AWS SDK', () => { }; const describeStackResourcesStub = sinon - .stub(awsSdk, 'request') + .stub(awsProvider, 'request') .returns(BbPromise.resolve({ StackResourceDetail: { PhysicalResourceId: 'serverlessDeploymentBucketName', }, })); - return awsSdk.getServerlessDeploymentBucketName(options.stage, options.region) + return awsProvider.getServerlessDeploymentBucketName(options.stage, options.region) .then((bucketName) => { expect(describeStackResourcesStub.calledOnce).to.be.equal(true); expect(describeStackResourcesStub.calledWith(options.stage, options.region)); expect(describeStackResourcesStub.args[0][0]).to.equal('CloudFormation'); expect(describeStackResourcesStub.args[0][1]).to.equal('describeStackResource'); expect(describeStackResourcesStub.args[0][2].StackName) - .to.equal(`${awsSdk.serverless.service.service}-${options.stage}`); + .to.equal(`${awsProvider.serverless.service.service}-${options.stage}`); expect(bucketName).to.equal('serverlessDeploymentBucketName'); - awsSdk.request.restore(); + awsProvider.request.restore(); }); }); }); @@ -375,7 +375,7 @@ describe('AWS SDK', () => { it('should return the stack name', () => { serverless.service.service = 'myservice'; - expect(awsSdk.getStackName('dev')).to.equal('myservice-dev'); + expect(awsProvider.getStackName('dev')).to.equal('myservice-dev'); }); }); }); diff --git a/tests/all.js b/tests/all.js index e15c40095..0880e686c 100644 --- a/tests/all.js +++ b/tests/all.js @@ -1,7 +1,7 @@ 'use strict'; // Serverless Core Tests -require('./classes/Serverless'); +require('../lib/Serverless.test'); require('./classes/PluginManager'); require('./classes/Utils'); require('./classes/Config'); @@ -22,7 +22,7 @@ require('../lib/plugins/package/tests/all'); require('../lib/plugins/slstats/tests/slstats'); // AWS Plugins Tests -require('../lib/plugins/aws/tests'); +require('../lib/plugins/awsProvider/awsProvider.test'); require('../lib/plugins/aws/tests/validate'); require('../lib/plugins/aws/tests/monitorStack'); require('../lib/plugins/aws/info/tests'); From a60a9b575b67a1468989466a3f7b6283c685e4ae Mon Sep 17 00:00:00 2001 From: Philipp Muens Date: Fri, 14 Oct 2016 19:39:03 -0700 Subject: [PATCH 2/8] Remove provider storage on PluginManager level --- lib/Serverless.js | 4 ---- lib/classes/PluginManager.js | 8 ++------ tests/classes/PluginManager.js | 15 +-------------- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/lib/Serverless.js b/lib/Serverless.js index bc9bdf814..61675bad9 100644 --- a/lib/Serverless.js +++ b/lib/Serverless.js @@ -60,10 +60,6 @@ class Serverless { return this.service.load(this.processedInput.options) .then(() => { - // set the provider of the service (so that the PluginManager takes care to - // execute the correct provider specific plugins) - this.pluginManager.setProvider(this.service.provider.name); - // load all plugins this.pluginManager.loadAllPlugins(this.service.plugins); diff --git a/lib/classes/PluginManager.js b/lib/classes/PluginManager.js index ef436481c..41213b4de 100644 --- a/lib/classes/PluginManager.js +++ b/lib/classes/PluginManager.js @@ -7,7 +7,6 @@ const _ = require('lodash'); class PluginManager { constructor(serverless) { this.serverless = serverless; - this.provider = null; this.cliOptions = {}; this.cliCommands = []; @@ -17,10 +16,6 @@ class PluginManager { this.hooks = {}; } - setProvider(provider) { - this.provider = provider; - } - setCliOptions(options) { this.cliOptions = options; } @@ -33,7 +28,8 @@ class PluginManager { const pluginInstance = new Plugin(this.serverless, this.cliOptions); // ignore plugins that specify a different provider than the current one - if (pluginInstance.provider && (pluginInstance.provider !== this.provider)) { + if (pluginInstance.provider + && (pluginInstance.provider !== this.serverless.service.provider.name)) { return; } diff --git a/tests/classes/PluginManager.js b/tests/classes/PluginManager.js index bd51119fc..90b69a47a 100644 --- a/tests/classes/PluginManager.js +++ b/tests/classes/PluginManager.js @@ -198,10 +198,6 @@ describe('PluginManager', () => { expect(pluginManager.serverless).to.deep.equal(serverless); }); - it('should create a nullified provider variable', () => { - expect(pluginManager.provider).to.equal(null); - }); - it('should create an empty cliOptions object', () => { expect(pluginManager.cliOptions).to.deep.equal({}); }); @@ -219,15 +215,6 @@ describe('PluginManager', () => { }); }); - describe('#setProvider()', () => { - it('should set the provider variable', () => { - const provider = 'provider1'; - pluginManager.setProvider(provider); - - expect(pluginManager.provider).to.equal(provider); - }); - }); - describe('#setCliOptions()', () => { it('should set the cliOptions object', () => { const options = { foo: 'bar' }; @@ -670,7 +657,7 @@ describe('PluginManager', () => { describe('when using provider specific plugins', () => { beforeEach(function () { // eslint-disable-line prefer-arrow-callback - pluginManager.setProvider('provider1'); + pluginManager.serverless.service.provider.name = 'provider1'; pluginManager.addPlugin(Provider1PluginMock); pluginManager.addPlugin(Provider2PluginMock); From 4a9dc58e18d21cfd1a3abf868fab2e5427f03268 Mon Sep 17 00:00:00 2001 From: Philipp Muens Date: Fri, 14 Oct 2016 20:41:30 -0700 Subject: [PATCH 3/8] Add string and instance powered provider check --- lib/classes/PluginManager.js | 14 ++++++- lib/plugins/awsProvider/awsProvider.js | 6 ++- lib/plugins/awsProvider/awsProvider.test.js | 14 ++++++- tests/classes/PluginManager.js | 45 +++++++++++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/lib/classes/PluginManager.js b/lib/classes/PluginManager.js index 41213b4de..27bec57c0 100644 --- a/lib/classes/PluginManager.js +++ b/lib/classes/PluginManager.js @@ -27,9 +27,19 @@ class PluginManager { addPlugin(Plugin) { const pluginInstance = new Plugin(this.serverless, this.cliOptions); + let pluginProvider = null; + // check if plugin is provider agnostic + if (pluginInstance.provider) { + if (typeof pluginInstance.provider === 'string') { + pluginProvider = pluginInstance.provider; + } else if (typeof pluginInstance.provider === 'object') { + pluginProvider = pluginInstance.provider.constructor.getProviderName(); + } + } + // ignore plugins that specify a different provider than the current one - if (pluginInstance.provider - && (pluginInstance.provider !== this.serverless.service.provider.name)) { + if (pluginProvider + && (pluginProvider !== this.serverless.service.provider.name)) { return; } diff --git a/lib/plugins/awsProvider/awsProvider.js b/lib/plugins/awsProvider/awsProvider.js index 6e4817877..6efa52be4 100644 --- a/lib/plugins/awsProvider/awsProvider.js +++ b/lib/plugins/awsProvider/awsProvider.js @@ -71,10 +71,14 @@ const impl = { }; class AwsProvider { + static getProviderName() { + return 'aws'; + } + constructor(serverless) { this.serverless = serverless; this.sdk = AWS; - + this.provider = this; // only load plugin in an AWS service context this.serverless.setProvider('aws', this); // Use HTTPS Proxy (Optional) diff --git a/lib/plugins/awsProvider/awsProvider.test.js b/lib/plugins/awsProvider/awsProvider.test.js index 0bf646ae4..8dde002d4 100644 --- a/lib/plugins/awsProvider/awsProvider.test.js +++ b/lib/plugins/awsProvider/awsProvider.test.js @@ -21,13 +21,23 @@ describe('AwsProvider', () => { awsProvider.serverless.cli = new serverless.classes.CLI(); }); + describe('#getProviderName()', () => { + it('should return the provider name', () => { + expect(AwsProvider.getProviderName()).to.equal('aws'); + }); + }); + describe('#constructor()', () => { + it('should set Serverless instance', () => { + expect(typeof awsProvider.serverless).to.not.equal('undefined'); + }); + it('should set AWS instance', () => { expect(typeof awsProvider.sdk).to.not.equal('undefined'); }); - it('should set Serverless instance', () => { - expect(typeof awsProvider.serverless).to.not.equal('undefined'); + it('should set the provider property', () => { + expect(awsProvider.provider).to.equal(awsProvider); }); it('should set AWS proxy', () => { diff --git a/tests/classes/PluginManager.js b/tests/classes/PluginManager.js index 90b69a47a..47ce9516c 100644 --- a/tests/classes/PluginManager.js +++ b/tests/classes/PluginManager.js @@ -281,6 +281,51 @@ describe('PluginManager', () => { expect(pluginManager.commands).to.have.property('deploy'); }); + + it('should skip service related plugins which not match the services provider', () => { + pluginManager.serverless.service.provider.name = 'someProvider'; + class Plugin { + constructor() { + this.provider = 'someOtherProvider'; + } + } + + pluginManager.addPlugin(Plugin); + + expect(pluginManager.plugins.length).to.equal(0); + }); + + it('should add service related plugins when provider property is the providers name', () => { + pluginManager.serverless.service.provider.name = 'someProvider'; + class Plugin { + constructor() { + this.provider = 'someProvider'; + } + } + + pluginManager.addPlugin(Plugin); + + expect(pluginManager.plugins[0]).to.be.an.instanceOf(Plugin); + }); + + it('should add service related plugins when provider propery is provider plugin', () => { + pluginManager.serverless.service.provider.name = 'someProvider'; + class ProviderPlugin { + static getProviderName() { + return 'someProvider'; + } + } + const providerPlugin = new ProviderPlugin(); + class Plugin { + constructor() { + this.provider = providerPlugin; + } + } + + pluginManager.addPlugin(Plugin); + + expect(pluginManager.plugins[0]).to.be.an.instanceOf(Plugin); + }); }); describe('#loadAllPlugins()', () => { From c7b7472a48003f294fd6e47d23a9220b6ff35ce6 Mon Sep 17 00:00:00 2001 From: Philipp Muens Date: Fri, 14 Oct 2016 21:33:27 -0700 Subject: [PATCH 4/8] Update provider properties in plugins --- lib/Serverless.test.js | 2 +- .../deploy/compile/events/apiGateway/index.js | 2 +- .../compile/events/apiGateway/tests/index.js | 7 ++-- .../aws/deploy/compile/events/s3/index.js | 2 +- .../deploy/compile/events/s3/tests/index.js | 6 ++- .../deploy/compile/events/schedule/index.js | 2 +- .../compile/events/schedule/tests/index.js | 6 ++- .../aws/deploy/compile/events/sns/index.js | 2 +- .../deploy/compile/events/sns/tests/index.js | 6 ++- .../aws/deploy/compile/events/stream/index.js | 2 +- .../compile/events/stream/tests/index.js | 6 ++- .../aws/deploy/compile/functions/index.js | 2 +- .../deploy/compile/functions/tests/index.js | 6 ++- lib/plugins/aws/deploy/index.js | 3 +- lib/plugins/aws/deploy/lib/cleanupS3Bucket.js | 4 +- lib/plugins/aws/deploy/lib/configureStack.js | 2 +- lib/plugins/aws/deploy/lib/createStack.js | 4 +- lib/plugins/aws/deploy/lib/setBucketName.js | 2 +- lib/plugins/aws/deploy/lib/updateStack.js | 2 +- lib/plugins/aws/deploy/lib/uploadArtifacts.js | 4 +- .../aws/deploy/tests/cleanupS3Bucket.js | 22 +++++------ .../aws/deploy/tests/configureStack.js | 8 ++-- lib/plugins/aws/deploy/tests/createStack.js | 18 ++++----- lib/plugins/aws/deploy/tests/index.js | 7 ++-- lib/plugins/aws/deploy/tests/setBucketName.js | 6 +-- lib/plugins/aws/deploy/tests/updateStack.js | 6 +-- .../aws/deploy/tests/uploadArtifacts.js | 12 +++--- lib/plugins/aws/deployFunction/index.js | 7 ++-- lib/plugins/aws/deployFunction/tests/index.js | 12 +++--- lib/plugins/aws/info/index.js | 9 ++--- lib/plugins/aws/info/tests/index.js | 26 ++++++------- lib/plugins/aws/invoke/index.js | 6 +-- lib/plugins/aws/invoke/tests/index.js | 12 +++--- lib/plugins/aws/lib/monitorStack.js | 2 +- lib/plugins/aws/logs/index.js | 7 ++-- lib/plugins/aws/logs/tests/index.js | 22 +++++------ lib/plugins/aws/remove/index.js | 3 +- lib/plugins/aws/remove/lib/bucket.js | 6 +-- lib/plugins/aws/remove/lib/stack.js | 2 +- lib/plugins/aws/remove/tests/bucket.js | 16 ++++---- lib/plugins/aws/remove/tests/index.js | 8 ++-- lib/plugins/aws/remove/tests/stack.js | 4 +- lib/plugins/aws/tests/monitorStack.js | 38 +++++++++---------- tests/classes/PluginManager.js | 2 +- 44 files changed, 171 insertions(+), 162 deletions(-) diff --git a/lib/Serverless.test.js b/lib/Serverless.test.js index 25e2b7737..3d9f44ede 100644 --- a/lib/Serverless.test.js +++ b/lib/Serverless.test.js @@ -110,7 +110,7 @@ describe('Serverless', () => { describe('#init()', () => { it('should create a new CLI instance', () => { serverless.init(); - expect(serverless.cli).to.be.instanceOf(CLI); + expect(serverless.cli).to.be.instanceof(CLI); }); // note: we just test that the processedInput variable is set (not the content of it) diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/index.js b/lib/plugins/aws/deploy/compile/events/apiGateway/index.js index ccf2db649..26f7c7fcf 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/index.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/index.js @@ -16,7 +16,7 @@ class AwsCompileApigEvents { constructor(serverless, options) { this.serverless = serverless; this.options = options; - this.provider = 'aws'; + this.provider = this.serverless.getProvider('aws'); Object.assign( this, diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js b/lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js index 4c7301b28..7237ea822 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js @@ -3,6 +3,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const BbPromise = require('bluebird'); +const AwsProvider = require('../../../../../../awsProvider/awsProvider'); const AwsCompileApigEvents = require('../index'); const Serverless = require('../../../../../../../Serverless'); @@ -39,7 +40,7 @@ describe('AwsCompileApigEvents', () => { stage: 'dev', region: 'us-east-1', }; - + serverless.setProvider('aws', new AwsProvider(serverless)); const awsCompileApigEvents = new AwsCompileApigEvents(serverless, options); describe('#constructor()', () => { @@ -47,8 +48,8 @@ describe('AwsCompileApigEvents', () => { it('should have hooks', () => expect(awsCompileApigEvents.hooks).to.be.not.empty); - it('should set the provider variable to "aws"', () => expect(awsCompileApigEvents.provider) - .to.equal('aws')); + it('should set the provider variable to be an instanceof AwsProvider', () => + expect(awsCompileApigEvents.provider).to.be.instanceof(AwsProvider)); it('should run promise chain in order', () => { const validateStub = sinon diff --git a/lib/plugins/aws/deploy/compile/events/s3/index.js b/lib/plugins/aws/deploy/compile/events/s3/index.js index fc849c786..11c8bd76f 100644 --- a/lib/plugins/aws/deploy/compile/events/s3/index.js +++ b/lib/plugins/aws/deploy/compile/events/s3/index.js @@ -5,7 +5,7 @@ const _ = require('lodash'); class AwsCompileS3Events { constructor(serverless) { this.serverless = serverless; - this.provider = 'aws'; + this.provider = this.serverless.getProvider('aws'); this.hooks = { 'deploy:compileEvents': this.compileS3Events.bind(this), diff --git a/lib/plugins/aws/deploy/compile/events/s3/tests/index.js b/lib/plugins/aws/deploy/compile/events/s3/tests/index.js index 9c504d946..62ebf2dc0 100644 --- a/lib/plugins/aws/deploy/compile/events/s3/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/s3/tests/index.js @@ -1,6 +1,7 @@ 'use strict'; const expect = require('chai').expect; +const AwsProvider = require('../../../../../../awsProvider/awsProvider'); const AwsCompileS3Events = require('../index'); const Serverless = require('../../../../../../../Serverless'); @@ -11,13 +12,14 @@ describe('AwsCompileS3Events', () => { beforeEach(() => { serverless = new Serverless(); serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} }; + serverless.setProvider('aws', new AwsProvider(serverless)); awsCompileS3Events = new AwsCompileS3Events(serverless); awsCompileS3Events.serverless.service.service = 'new-service'; }); describe('#constructor()', () => { - it('should set the provider variable to "aws"', () => expect(awsCompileS3Events.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsCompileS3Events.provider).to.be.instanceof(AwsProvider)); }); describe('#compileS3Events()', () => { diff --git a/lib/plugins/aws/deploy/compile/events/schedule/index.js b/lib/plugins/aws/deploy/compile/events/schedule/index.js index 5e06de37c..b5f72782b 100644 --- a/lib/plugins/aws/deploy/compile/events/schedule/index.js +++ b/lib/plugins/aws/deploy/compile/events/schedule/index.js @@ -5,7 +5,7 @@ const _ = require('lodash'); class AwsCompileScheduledEvents { constructor(serverless) { this.serverless = serverless; - this.provider = 'aws'; + this.provider = this.serverless.getProvider('aws'); this.hooks = { 'deploy:compileEvents': this.compileScheduledEvents.bind(this), diff --git a/lib/plugins/aws/deploy/compile/events/schedule/tests/index.js b/lib/plugins/aws/deploy/compile/events/schedule/tests/index.js index e71842dfa..b11882bc3 100644 --- a/lib/plugins/aws/deploy/compile/events/schedule/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/schedule/tests/index.js @@ -1,6 +1,7 @@ 'use strict'; const expect = require('chai').expect; +const AwsProvider = require('../../../../../../awsProvider/awsProvider'); const AwsCompileScheduledEvents = require('../index'); const Serverless = require('../../../../../../../Serverless'); @@ -11,13 +12,14 @@ describe('AwsCompileScheduledEvents', () => { beforeEach(() => { serverless = new Serverless(); serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} }; + serverless.setProvider('aws', new AwsProvider(serverless)); awsCompileScheduledEvents = new AwsCompileScheduledEvents(serverless); awsCompileScheduledEvents.serverless.service.service = 'new-service'; }); describe('#constructor()', () => { - it('should set the provider variable to "aws"', () => expect(awsCompileScheduledEvents.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsCompileScheduledEvents.provider).to.be.instanceof(AwsProvider)); }); describe('#compileScheduledEvents()', () => { diff --git a/lib/plugins/aws/deploy/compile/events/sns/index.js b/lib/plugins/aws/deploy/compile/events/sns/index.js index c935bebab..4576949b7 100644 --- a/lib/plugins/aws/deploy/compile/events/sns/index.js +++ b/lib/plugins/aws/deploy/compile/events/sns/index.js @@ -5,7 +5,7 @@ const _ = require('lodash'); class AwsCompileSNSEvents { constructor(serverless) { this.serverless = serverless; - this.provider = 'aws'; + this.provider = this.serverless.getProvider('aws'); this.hooks = { 'deploy:compileEvents': this.compileSNSEvents.bind(this), diff --git a/lib/plugins/aws/deploy/compile/events/sns/tests/index.js b/lib/plugins/aws/deploy/compile/events/sns/tests/index.js index f9021c06c..295c0e883 100644 --- a/lib/plugins/aws/deploy/compile/events/sns/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/sns/tests/index.js @@ -1,6 +1,7 @@ 'use strict'; const expect = require('chai').expect; +const AwsProvider = require('../../../../../../awsProvider/awsProvider'); const AwsCompileSNSEvents = require('../index'); const Serverless = require('../../../../../../../Serverless'); @@ -11,12 +12,13 @@ describe('AwsCompileSNSEvents', () => { beforeEach(() => { serverless = new Serverless(); serverless.service.provider.compiledCloudFormationTemplate = { Resources: {} }; + serverless.setProvider('aws', new AwsProvider(serverless)); awsCompileSNSEvents = new AwsCompileSNSEvents(serverless); }); describe('#constructor()', () => { - it('should set the provider variable to "aws"', () => expect(awsCompileSNSEvents.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsCompileSNSEvents.provider).to.be.instanceof(AwsProvider)); }); describe('#compileSNSEvents()', () => { diff --git a/lib/plugins/aws/deploy/compile/events/stream/index.js b/lib/plugins/aws/deploy/compile/events/stream/index.js index 861103da5..7f4378a0f 100644 --- a/lib/plugins/aws/deploy/compile/events/stream/index.js +++ b/lib/plugins/aws/deploy/compile/events/stream/index.js @@ -5,7 +5,7 @@ const _ = require('lodash'); class AwsCompileStreamEvents { constructor(serverless) { this.serverless = serverless; - this.provider = 'aws'; + this.provider = this.serverless.getProvider('aws'); this.hooks = { 'deploy:compileEvents': this.compileStreamEvents.bind(this), diff --git a/lib/plugins/aws/deploy/compile/events/stream/tests/index.js b/lib/plugins/aws/deploy/compile/events/stream/tests/index.js index 0dcabb175..873c38033 100644 --- a/lib/plugins/aws/deploy/compile/events/stream/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/stream/tests/index.js @@ -1,6 +1,7 @@ 'use strict'; const expect = require('chai').expect; +const AwsProvider = require('../../../../../../awsProvider/awsProvider'); const AwsCompileStreamEvents = require('../index'); const Serverless = require('../../../../../../../Serverless'); @@ -21,13 +22,14 @@ describe('AwsCompileStreamEvents', () => { }, }, }; + serverless.setProvider('aws', new AwsProvider(serverless)); awsCompileStreamEvents = new AwsCompileStreamEvents(serverless); awsCompileStreamEvents.serverless.service.service = 'new-service'; }); describe('#constructor()', () => { - it('should set the provider variable to "aws"', () => expect(awsCompileStreamEvents.provider) - .to.equal('aws')); + it('should set the provider variable to be an instance of AwsProvider', () => + expect(awsCompileStreamEvents.provider).to.be.instanceof(AwsProvider)); }); describe('#compileStreamEvents()', () => { diff --git a/lib/plugins/aws/deploy/compile/functions/index.js b/lib/plugins/aws/deploy/compile/functions/index.js index bbdaf3fce..943d0ae2d 100644 --- a/lib/plugins/aws/deploy/compile/functions/index.js +++ b/lib/plugins/aws/deploy/compile/functions/index.js @@ -7,7 +7,7 @@ class AwsCompileFunctions { constructor(serverless, options) { this.serverless = serverless; this.options = options; - this.provider = 'aws'; + this.provider = this.serverless.getProvider('aws'); this.compileFunctions = this.compileFunctions.bind(this); this.compileFunction = this.compileFunction.bind(this); diff --git a/lib/plugins/aws/deploy/compile/functions/tests/index.js b/lib/plugins/aws/deploy/compile/functions/tests/index.js index 1f2ce8787..395da587a 100644 --- a/lib/plugins/aws/deploy/compile/functions/tests/index.js +++ b/lib/plugins/aws/deploy/compile/functions/tests/index.js @@ -2,6 +2,7 @@ const path = require('path'); const expect = require('chai').expect; +const AwsProvider = require('../../../../../awsProvider/awsProvider'); const AwsCompileFunctions = require('../index'); const Serverless = require('../../../../../../Serverless'); @@ -17,6 +18,7 @@ describe('AwsCompileFunctions', () => { stage: 'dev', region: 'us-east-1', }; + serverless.setProvider('aws', new AwsProvider(serverless)); awsCompileFunctions = new AwsCompileFunctions(serverless, options); awsCompileFunctions.serverless.service.provider.compiledCloudFormationTemplate = { Resources: {}, @@ -34,8 +36,8 @@ describe('AwsCompileFunctions', () => { }); describe('#constructor()', () => { - it('should set the provider variable to "aws"', () => expect(awsCompileFunctions.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsCompileFunctions.provider).to.be.instanceof(AwsProvider)); }); describe('#compileFunctions()', () => { diff --git a/lib/plugins/aws/deploy/index.js b/lib/plugins/aws/deploy/index.js index 91da5ef9e..53cbf0a5d 100644 --- a/lib/plugins/aws/deploy/index.js +++ b/lib/plugins/aws/deploy/index.js @@ -16,8 +16,7 @@ class AwsDeploy { constructor(serverless, options) { this.serverless = serverless; this.options = options; - this.provider = 'aws'; - this.aws = this.serverless.getProvider(this.provider); + this.provider = this.serverless.getProvider('aws'); Object.assign( this, diff --git a/lib/plugins/aws/deploy/lib/cleanupS3Bucket.js b/lib/plugins/aws/deploy/lib/cleanupS3Bucket.js index 26a69b8c9..7aa4196b6 100644 --- a/lib/plugins/aws/deploy/lib/cleanupS3Bucket.js +++ b/lib/plugins/aws/deploy/lib/cleanupS3Bucket.js @@ -9,7 +9,7 @@ module.exports = { const directoriesToKeepCount = 4; const serviceStage = `${this.serverless.service.service}/${this.options.stage}`; - return this.aws.request('S3', + return this.provider.request('S3', 'listObjectsV2', { Bucket: this.bucketName, @@ -62,7 +62,7 @@ module.exports = { if (objectsToRemove && objectsToRemove.length) { this.serverless.cli.log('Removing old service versions...'); - return this.aws.request('S3', + return this.provider.request('S3', 'deleteObjects', { Bucket: this.bucketName, diff --git a/lib/plugins/aws/deploy/lib/configureStack.js b/lib/plugins/aws/deploy/lib/configureStack.js index d0831dc41..4518a31de 100644 --- a/lib/plugins/aws/deploy/lib/configureStack.js +++ b/lib/plugins/aws/deploy/lib/configureStack.js @@ -79,7 +79,7 @@ module.exports = { if (bucketName) { return BbPromise.bind(this) .then(() => this.validateS3BucketName(bucketName)) - .then(() => this.aws.request('S3', + .then(() => this.provider.request('S3', 'getBucketLocation', { Bucket: bucketName, diff --git a/lib/plugins/aws/deploy/lib/createStack.js b/lib/plugins/aws/deploy/lib/createStack.js index be3113299..73fa76863 100644 --- a/lib/plugins/aws/deploy/lib/createStack.js +++ b/lib/plugins/aws/deploy/lib/createStack.js @@ -27,7 +27,7 @@ module.exports = { Tags: Object.keys(stackTags).map((key) => ({ Key: key, Value: stackTags[key] })), }; - return this.aws.request('CloudFormation', + return this.provider.request('CloudFormation', 'createStack', params, this.options.stage, @@ -55,7 +55,7 @@ module.exports = { return BbPromise.resolve(); } - return this.aws.request('CloudFormation', + return this.provider.request('CloudFormation', 'describeStackResources', { StackName: stackName }, this.options.stage, diff --git a/lib/plugins/aws/deploy/lib/setBucketName.js b/lib/plugins/aws/deploy/lib/setBucketName.js index db7fef659..8765ac656 100644 --- a/lib/plugins/aws/deploy/lib/setBucketName.js +++ b/lib/plugins/aws/deploy/lib/setBucketName.js @@ -12,7 +12,7 @@ module.exports = { return BbPromise.resolve(); } - return this.aws.getServerlessDeploymentBucketName(this.options.stage, this.options.region) + return this.provider.getServerlessDeploymentBucketName(this.options.stage, this.options.region) .then((bucketName) => { this.bucketName = bucketName; }); diff --git a/lib/plugins/aws/deploy/lib/updateStack.js b/lib/plugins/aws/deploy/lib/updateStack.js index 1b74fd8cf..819a3032d 100644 --- a/lib/plugins/aws/deploy/lib/updateStack.js +++ b/lib/plugins/aws/deploy/lib/updateStack.js @@ -39,7 +39,7 @@ module.exports = { }); } - return this.aws.request('CloudFormation', + return this.provider.request('CloudFormation', 'updateStack', params, this.options.stage, diff --git a/lib/plugins/aws/deploy/lib/uploadArtifacts.js b/lib/plugins/aws/deploy/lib/uploadArtifacts.js index e3c66088b..e53d14b89 100644 --- a/lib/plugins/aws/deploy/lib/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/lib/uploadArtifacts.js @@ -19,7 +19,7 @@ module.exports = { ContentType: 'application/json', }; - return this.aws.request('S3', + return this.provider.request('S3', 'putObject', params, this.options.stage, @@ -42,7 +42,7 @@ module.exports = { ContentType: 'application/zip', }; - return this.aws.request('S3', + return this.provider.request('S3', 'putObject', params, this.options.stage, diff --git a/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js b/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js index ae98295b2..7cb72b387 100644 --- a/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js +++ b/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js @@ -33,7 +33,7 @@ describe('cleanupS3Bucket', () => { }; const listObjectsStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve(serviceObjects)); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve(serviceObjects)); return awsDeploy.getObjectsToRemove().then(() => { expect(listObjectsStub.calledOnce).to.be.equal(true); @@ -42,7 +42,7 @@ describe('cleanupS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(listObjectsStub.args[0][2].Prefix).to.be.equal(`${s3Key}`); expect(listObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); @@ -65,7 +65,7 @@ describe('cleanupS3Bucket', () => { }; const listObjectsStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve(serviceObjects)); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve(serviceObjects)); return awsDeploy.getObjectsToRemove().then((objectsToRemove) => { expect(objectsToRemove).to.not @@ -106,7 +106,7 @@ describe('cleanupS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(listObjectsStub.args[0][2].Prefix).to.be.equal(`${s3Key}`); expect(listObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); @@ -123,7 +123,7 @@ describe('cleanupS3Bucket', () => { }; const listObjectsStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve(serviceObjects)); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve(serviceObjects)); return awsDeploy.getObjectsToRemove().then((objectsToRemove) => { expect(objectsToRemove.length).to.equal(0); @@ -133,7 +133,7 @@ describe('cleanupS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(listObjectsStub.args[0][2].Prefix).to.be.equal(`${s3Key}`); expect(listObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); @@ -152,7 +152,7 @@ describe('cleanupS3Bucket', () => { }; const listObjectsStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve(serviceObjects)); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve(serviceObjects)); return awsDeploy.getObjectsToRemove().then((objectsToRemove) => { expect(objectsToRemove.length).to.equal(0); @@ -162,7 +162,7 @@ describe('cleanupS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(listObjectsStub.args[0][2].Prefix).to.be.equal(`${s3Key}`); expect(listObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); }); @@ -172,13 +172,13 @@ describe('cleanupS3Bucket', () => { beforeEach(() => { deleteObjectsStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); }); it('should resolve if no service objects are found in the S3 bucket', () => awsDeploy .removeObjects().then(() => { expect(deleteObjectsStub.calledOnce).to.be.equal(false); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }) ); @@ -197,7 +197,7 @@ describe('cleanupS3Bucket', () => { expect(deleteObjectsStub.args[0][2].Bucket).to.be.equal(awsDeploy.bucketName); expect(deleteObjectsStub.args[0][2].Delete.Objects).to.be.equal(objectsToRemove); expect(deleteObjectsStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); }); diff --git a/lib/plugins/aws/deploy/tests/configureStack.js b/lib/plugins/aws/deploy/tests/configureStack.js index 606f8bbae..3eae9ce9c 100644 --- a/lib/plugins/aws/deploy/tests/configureStack.js +++ b/lib/plugins/aws/deploy/tests/configureStack.js @@ -16,7 +16,7 @@ describe('#configureStack', () => { beforeEach(() => { serverless = new Serverless(); awsPlugin.serverless = serverless; - awsPlugin.aws = new AwsProvider(serverless); + awsPlugin.provider = new AwsProvider(serverless); awsPlugin.options = { stage: 'dev', region: 'us-east-1', @@ -29,7 +29,7 @@ describe('#configureStack', () => { const bucketName = 'com.serverless.deploys'; const getBucketLocationStub = sinon - .stub(awsPlugin.aws, 'request').returns( + .stub(awsPlugin.provider, 'request').returns( BbPromise.resolve({ LocationConstraint: awsPlugin.options.region }) ); @@ -46,7 +46,7 @@ describe('#configureStack', () => { const bucketName = 'com.serverless.deploys'; const createStackStub = sinon - .stub(awsPlugin.aws, 'request').returns( + .stub(awsPlugin.provider, 'request').returns( BbPromise.resolve({ LocationConstraint: 'us-west-1' }) ); @@ -156,7 +156,7 @@ describe('#configureStack', () => { .compiledCloudFormationTemplate = coreCloudFormationTemplate; sinon - .stub(awsPlugin.aws, 'request') + .stub(awsPlugin.provider, 'request') .returns(BbPromise.resolve({ LocationConstraint: awsPlugin.options.region })); return awsPlugin.configureStack() diff --git a/lib/plugins/aws/deploy/tests/createStack.js b/lib/plugins/aws/deploy/tests/createStack.js index b821fa793..463369602 100644 --- a/lib/plugins/aws/deploy/tests/createStack.js +++ b/lib/plugins/aws/deploy/tests/createStack.js @@ -51,7 +51,7 @@ describe('createStack', () => { .compiledCloudFormationTemplate = coreCloudFormationTemplate; const createStackStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); return awsDeploy.create().then(() => { expect(createStackStub.args[0][0]).to.equal('CloudFormation'); @@ -71,7 +71,7 @@ describe('createStack', () => { awsDeploy.serverless.service.provider.stackTags = { STAGE: 'overridden', tag1: 'value1' }; const createStackStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); return awsDeploy.create().then(() => { expect(createStackStub.args[0][2].Tags) @@ -79,14 +79,14 @@ describe('createStack', () => { { Key: 'STAGE', Value: 'overridden' }, { Key: 'tag1', Value: 'value1' }, ]); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); }); describe('#createStack()', () => { it('should store the core CloudFormation template in the provider object', () => { - sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); const coreCloudFormationTemplate = awsDeploy.serverless.utils.readFileSync( path.join(__dirname, @@ -112,7 +112,7 @@ describe('createStack', () => { const createStub = sinon .stub(awsDeploy, 'create').returns(BbPromise.resolve()); - sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); return awsDeploy.createStack().then(() => { expect(createStub.called).to.be.equal(false); @@ -138,11 +138,11 @@ describe('createStack', () => { const writeCreateTemplateToDiskStub = sinon .stub(awsDeploy, 'writeCreateTemplateToDisk').returns(BbPromise.resolve()); - sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); return awsDeploy.createStack().then((res) => { expect(writeCreateTemplateToDiskStub.calledOnce).to.be.equal(true); - expect(awsDeploy.aws.request.called).to.be.equal(true); + expect(awsDeploy.provider.request.called).to.be.equal(true); expect(res).to.equal('alreadyCreated'); }); }); @@ -152,7 +152,7 @@ describe('createStack', () => { message: 'Something went wrong.', }; - sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.reject(errorMock)); + sinon.stub(awsDeploy.provider, 'request').returns(BbPromise.reject(errorMock)); const createStub = sinon .stub(awsDeploy, 'create').returns(BbPromise.resolve()); @@ -169,7 +169,7 @@ describe('createStack', () => { message: 'does not exist', }; - sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.reject(errorMock)); + sinon.stub(awsDeploy.provider, 'request').returns(BbPromise.reject(errorMock)); const createStub = sinon .stub(awsDeploy, 'create').returns(BbPromise.resolve()); diff --git a/lib/plugins/aws/deploy/tests/index.js b/lib/plugins/aws/deploy/tests/index.js index d5f3de785..af38cab45 100644 --- a/lib/plugins/aws/deploy/tests/index.js +++ b/lib/plugins/aws/deploy/tests/index.js @@ -1,5 +1,6 @@ 'use strict'; +const AwsProvider = require('../../../awsProvider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const expect = require('chai').expect; @@ -14,7 +15,7 @@ describe('AwsDeploy', () => { stage: 'dev', region: 'us-east-1', }; - + serverless.setProvider('aws', new AwsProvider(serverless)); awsDeploy = new AwsDeploy(serverless, options); awsDeploy.serverless.cli = new serverless.classes.CLI(); }); @@ -22,8 +23,8 @@ describe('AwsDeploy', () => { describe('#constructor()', () => { it('should have hooks', () => expect(awsDeploy.hooks).to.be.not.empty); - it('should set the provider variable to "aws"', () => expect(awsDeploy.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsDeploy.provider).to.be.instanceof(AwsProvider)); }); describe('hooks', () => { diff --git a/lib/plugins/aws/deploy/tests/setBucketName.js b/lib/plugins/aws/deploy/tests/setBucketName.js index 95e56b321..d1c75950a 100644 --- a/lib/plugins/aws/deploy/tests/setBucketName.js +++ b/lib/plugins/aws/deploy/tests/setBucketName.js @@ -22,7 +22,7 @@ describe('#setBucketName()', () => { awsDeploy = new AwsDeploy(serverless, options); getServerlessDeploymentBucketNameStub = sinon - .stub(awsDeploy.aws, 'getServerlessDeploymentBucketName') + .stub(awsDeploy.provider, 'getServerlessDeploymentBucketName') .returns(BbPromise.resolve('bucket-name')); }); @@ -32,7 +32,7 @@ describe('#setBucketName()', () => { expect(getServerlessDeploymentBucketNameStub.calledOnce).to.be.equal(true); expect(getServerlessDeploymentBucketNameStub .calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.getServerlessDeploymentBucketName.restore(); + awsDeploy.provider.getServerlessDeploymentBucketName.restore(); }) ); @@ -41,7 +41,7 @@ describe('#setBucketName()', () => { return awsDeploy.setBucketName().then(() => { expect(getServerlessDeploymentBucketNameStub.calledOnce).to.be.equal(false); - awsDeploy.aws.getServerlessDeploymentBucketName.restore(); + awsDeploy.provider.getServerlessDeploymentBucketName.restore(); }); }); diff --git a/lib/plugins/aws/deploy/tests/updateStack.js b/lib/plugins/aws/deploy/tests/updateStack.js index e2d54a532..9d9046b77 100644 --- a/lib/plugins/aws/deploy/tests/updateStack.js +++ b/lib/plugins/aws/deploy/tests/updateStack.js @@ -36,7 +36,7 @@ describe('updateStack', () => { beforeEach(() => { updateStackStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); }); it('should update the stack', () => awsDeploy.update() @@ -53,7 +53,7 @@ describe('updateStack', () => { .to.deep.equal([{ Key: 'STAGE', Value: awsDeploy.options.stage }]); expect(updateStackStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }) ); @@ -76,7 +76,7 @@ describe('updateStack', () => { .to.equal( '{"Statement":[{"Effect":"Allow","Principal":"*","Action":"Update:*","Resource":"*"}]}' ); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); }); diff --git a/lib/plugins/aws/deploy/tests/uploadArtifacts.js b/lib/plugins/aws/deploy/tests/uploadArtifacts.js index 139a432ec..1b1548c82 100644 --- a/lib/plugins/aws/deploy/tests/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/tests/uploadArtifacts.js @@ -31,7 +31,7 @@ describe('uploadArtifacts', () => { awsDeploy.serverless.service.provider.compiledCloudFormationTemplate = { key: 'value' }; const putObjectStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); return awsDeploy.uploadCloudFormationFile().then(() => { expect(putObjectStub.calledOnce).to.be.equal(true); @@ -46,19 +46,19 @@ describe('uploadArtifacts', () => { .provider.compiledCloudFormationTemplate)); expect(putObjectStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); }); describe('#uploadZipFile()', () => { it('should throw for null artifact paths', () => { - sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); expect(() => awsDeploy.uploadZipFile(null)).to.throw(Error); }); it('should throw for empty artifact paths', () => { - sinon.stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + sinon.stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); expect(() => awsDeploy.uploadZipFile('')).to.throw(Error); }); @@ -70,7 +70,7 @@ describe('uploadArtifacts', () => { const artifactFileBuffer = serverless.utils.readFileSync(artifactFilePath); const putObjectStub = sinon - .stub(awsDeploy.aws, 'request').returns(BbPromise.resolve()); + .stub(awsDeploy.provider, 'request').returns(BbPromise.resolve()); return awsDeploy.uploadZipFile(artifactFilePath).then(() => { expect(putObjectStub.calledOnce).to.be.equal(true); @@ -84,7 +84,7 @@ describe('uploadArtifacts', () => { .to.be.equal(artifactFileBuffer.toString()); expect(putObjectStub.calledWith(awsDeploy.options.stage, awsDeploy.options.region)); - awsDeploy.aws.request.restore(); + awsDeploy.provider.request.restore(); }); }); }); diff --git a/lib/plugins/aws/deployFunction/index.js b/lib/plugins/aws/deployFunction/index.js index f2b166917..4075dfd64 100644 --- a/lib/plugins/aws/deployFunction/index.js +++ b/lib/plugins/aws/deployFunction/index.js @@ -11,8 +11,7 @@ class AwsDeployFunction { constructor(serverless, options) { this.serverless = serverless; this.options = options || {}; - this.provider = 'aws'; - this.aws = this.serverless.getProvider(this.provider); + this.provider = this.serverless.getProvider('aws'); this.pkg = new Package(this.serverless, this.options); @@ -37,7 +36,7 @@ class AwsDeployFunction { FunctionName: this.options.functionObj.name, }; - this.aws.request( + this.provider.request( 'Lambda', 'getFunction', params, @@ -68,7 +67,7 @@ class AwsDeployFunction { ZipFile: data, }; - return this.aws.request( + return this.provider.request( 'Lambda', 'updateFunctionCode', params, diff --git a/lib/plugins/aws/deployFunction/tests/index.js b/lib/plugins/aws/deployFunction/tests/index.js index 9887db139..3d0650921 100644 --- a/lib/plugins/aws/deployFunction/tests/index.js +++ b/lib/plugins/aws/deployFunction/tests/index.js @@ -52,8 +52,8 @@ describe('AwsDeployFunction', () => { describe('#constructor()', () => { it('should have hooks', () => expect(awsDeployFunction.hooks).to.be.not.empty); - it('should set the provider variable to "aws"', () => expect(awsDeployFunction.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsDeployFunction.provider).to.be.instanceof(AwsProvider)); it('should set an empty options object if no options are given', () => { const awsDeployFunctionWithEmptyOptions = new AwsDeployFunction(serverless); @@ -100,7 +100,7 @@ describe('AwsDeployFunction', () => { it('should check if the function is deployed', () => { const getFunctionStub = sinon - .stub(awsDeployFunction.aws, 'request').returns(BbPromise.resolve()); + .stub(awsDeployFunction.provider, 'request').returns(BbPromise.resolve()); awsDeployFunction.serverless.service.functions = { first: { @@ -117,7 +117,7 @@ describe('AwsDeployFunction', () => { expect(getFunctionStub.args[0][0]).to.be.equal('Lambda'); expect(getFunctionStub.args[0][1]).to.be.equal('getFunction'); expect(getFunctionStub.args[0][2].FunctionName).to.be.equal('first'); - awsDeployFunction.aws.request.restore(); + awsDeployFunction.provider.request.restore(); }); }); }); @@ -151,7 +151,7 @@ describe('AwsDeployFunction', () => { awsDeployFunction.options.functionObj.artifact = artifactFilePath; const updateFunctionCodeStub = sinon - .stub(awsDeployFunction.aws, 'request').returns(BbPromise.resolve()); + .stub(awsDeployFunction.provider, 'request').returns(BbPromise.resolve()); return awsDeployFunction.deployFunction().then(() => { const data = fs.readFileSync(artifactFilePath); @@ -164,7 +164,7 @@ describe('AwsDeployFunction', () => { expect(updateFunctionCodeStub.args[0][1]).to.be.equal('updateFunctionCode'); expect(updateFunctionCodeStub.args[0][2].FunctionName).to.be.equal('first'); expect(updateFunctionCodeStub.args[0][2].ZipFile).to.deep.equal(data); - awsDeployFunction.aws.request.restore(); + awsDeployFunction.provider.request.restore(); }); }); }); diff --git a/lib/plugins/aws/info/index.js b/lib/plugins/aws/info/index.js index 336313241..915c87462 100644 --- a/lib/plugins/aws/info/index.js +++ b/lib/plugins/aws/info/index.js @@ -8,8 +8,7 @@ const _ = require('lodash'); class AwsInfo { constructor(serverless, options) { this.serverless = serverless; - this.provider = 'aws'; - this.aws = this.serverless.getProvider(this.provider); + this.provider = this.serverless.getProvider('aws'); this.options = options || {}; Object.assign(this, validate); @@ -36,7 +35,7 @@ class AwsInfo { * Gather information about the service */ gather() { - const stackName = this.aws.getStackName(this.options.stage); + const stackName = this.provider.getStackName(this.options.stage); const info = { service: this.serverless.service.service, stage: this.options.stage, @@ -44,7 +43,7 @@ class AwsInfo { }; // Get info from CloudFormation Outputs - return this.aws.request('CloudFormation', + return this.provider.request('CloudFormation', 'describeStacks', { StackName: stackName }, this.options.stage, @@ -112,7 +111,7 @@ class AwsInfo { const apiKeyNames = this.serverless.service.provider.apiKeys || []; if (apiKeyNames.length) { - return this.aws.request('APIGateway', + return this.provider.request('APIGateway', 'getApiKeys', { includeValues: true }, this.options.stage, diff --git a/lib/plugins/aws/info/tests/index.js b/lib/plugins/aws/info/tests/index.js index 94755fcb5..8eeb97837 100644 --- a/lib/plugins/aws/info/tests/index.js +++ b/lib/plugins/aws/info/tests/index.js @@ -43,8 +43,8 @@ describe('AwsInfo', () => { describe('#constructor()', () => { it('should have hooks', () => expect(awsInfo.hooks).to.be.not.empty); - it('should set the provider variable to "aws"', () => expect(awsInfo.provider) - .to.equal('aws')); + it('should set the provider variable to the AwsProvider instance', () => + expect(awsInfo.provider).to.be.instanceof(AwsProvider)); it('should set an empty options object if no options are given', () => { const awsInfoWithEmptyOptions = new AwsInfo(serverless); @@ -160,7 +160,7 @@ describe('AwsInfo', () => { ], }; - const describeStackStub = sinon.stub(awsInfo.aws, 'request') + const describeStackStub = sinon.stub(awsInfo.provider, 'request') .returns(BbPromise.resolve(describeStacksResponse)); it('should gather with correct params', () => awsInfo.gather() @@ -169,7 +169,7 @@ describe('AwsInfo', () => { expect(describeStackStub.args[0][0]).to.equal('CloudFormation'); expect(describeStackStub.args[0][1]).to.equal('describeStacks'); expect(describeStackStub.args[0][2].StackName) - .to.equal(awsInfo.aws.getStackName(awsInfo.options.stage)); + .to.equal(awsInfo.provider.getStackName(awsInfo.options.stage)); expect(describeStackStub .calledWith(awsInfo.options.stage, awsInfo.options.region)); }) @@ -221,7 +221,7 @@ describe('AwsInfo', () => { }); it("should provide only general info when stack doesn't exist (ValidationError)", () => { - awsInfo.aws.request.restore(); + awsInfo.provider.request.restore(); serverless.service.service = 'my-first'; const validationError = { @@ -229,7 +229,7 @@ describe('AwsInfo', () => { message: 'Stack with id not-created-service does not exist', }; - sinon.stub(awsInfo.aws, 'request').returns(BbPromise.reject(validationError)); + sinon.stub(awsInfo.provider, 'request').returns(BbPromise.reject(validationError)); const expectedInfo = { service: 'my-first', @@ -243,8 +243,8 @@ describe('AwsInfo', () => { }); it('should throw a ServerlessError when AWS sdk throws an error', () => { - awsInfo.aws.request.restore(); - sinon.stub(awsInfo.aws, 'request').returns(BbPromise.reject(Error)); + awsInfo.provider.request.restore(); + sinon.stub(awsInfo.provider, 'request').returns(BbPromise.reject(Error)); return awsInfo.gather().catch((e) => { expect(e.name).to.equal('ServerlessError'); @@ -255,7 +255,7 @@ describe('AwsInfo', () => { describe('#getApiKeyValues()', () => { it('should return the api keys in the info object', () => { // TODO: implement a pattern for stub restoring to get rid of this - awsInfo.aws.request.restore(); + awsInfo.provider.request.restore(); // set the API Keys for the service awsInfo.serverless.service.provider.apiKeys = ['foo', 'bar']; @@ -297,14 +297,14 @@ describe('AwsInfo', () => { }; const getApiKeysStub = sinon - .stub(awsInfo.aws, 'request') + .stub(awsInfo.provider, 'request') .returns(BbPromise.resolve(apiKeyItems)); return awsInfo.getApiKeyValues(gatheredData).then((result) => { expect(getApiKeysStub.calledOnce).to.equal(true); expect(result.info.apiKeys).to.deep.equal(gatheredDataAfterKeyLookup.info.apiKeys); - awsInfo.aws.request.restore(); + awsInfo.provider.request.restore(); }); }); @@ -319,14 +319,14 @@ describe('AwsInfo', () => { }; const getApiKeysStub = sinon - .stub(awsInfo.aws, 'request') + .stub(awsInfo.provider, 'request') .returns(BbPromise.resolve()); return awsInfo.getApiKeyValues(gatheredData).then((result) => { expect(getApiKeysStub.calledOnce).to.equal(false); expect(result).to.deep.equal(gatheredData); - awsInfo.aws.request.restore(); + awsInfo.provider.request.restore(); }); }); }); diff --git a/lib/plugins/aws/invoke/index.js b/lib/plugins/aws/invoke/index.js index a39b97fe9..9d2ef8bcf 100644 --- a/lib/plugins/aws/invoke/index.js +++ b/lib/plugins/aws/invoke/index.js @@ -10,8 +10,7 @@ class AwsInvoke { constructor(serverless, options) { this.serverless = serverless; this.options = options || {}; - this.provider = 'aws'; - this.aws = this.serverless.getProvider(this.provider); + this.provider = this.serverless.getProvider('aws'); Object.assign(this, validate); @@ -57,7 +56,8 @@ class AwsInvoke { Payload: new Buffer(JSON.stringify(this.options.data || {})), }; - return this.aws.request('Lambda', 'invoke', params, this.options.stage, this.options.region); + return this.provider + .request('Lambda', 'invoke', params, this.options.stage, this.options.region); } log(invocationReply) { diff --git a/lib/plugins/aws/invoke/tests/index.js b/lib/plugins/aws/invoke/tests/index.js index 7ec519f92..3f1f2c8bf 100644 --- a/lib/plugins/aws/invoke/tests/index.js +++ b/lib/plugins/aws/invoke/tests/index.js @@ -22,8 +22,8 @@ describe('AwsInvoke', () => { describe('#constructor()', () => { it('should have hooks', () => expect(awsInvoke.hooks).to.be.not.empty); - it('should set the provider variable to "aws"', () => expect(awsInvoke.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsInvoke.provider).to.be.instanceof(AwsProvider)); it('should run promise chain in order', () => { const validateStub = sinon @@ -138,7 +138,7 @@ describe('AwsInvoke', () => { describe('#invoke()', () => { let invokeStub; beforeEach(() => { - invokeStub = sinon.stub(awsInvoke.aws, 'request').returns(BbPromise.resolve()); + invokeStub = sinon.stub(awsInvoke.provider, 'request').returns(BbPromise.resolve()); awsInvoke.serverless.service.service = 'new-service'; awsInvoke.options = { stage: 'dev', @@ -157,7 +157,7 @@ describe('AwsInvoke', () => { expect(invokeStub.args[0][2].InvocationType).to.be.equal('RequestResponse'); expect(invokeStub.args[0][2].LogType).to.be.equal('None'); expect(typeof invokeStub.args[0][2].Payload).to.not.be.equal('undefined'); - awsInvoke.aws.request.restore(); + awsInvoke.provider.request.restore(); }) ); @@ -171,7 +171,7 @@ describe('AwsInvoke', () => { expect(invokeStub.args[0][2].InvocationType).to.be.equal('RequestResponse'); expect(invokeStub.args[0][2].LogType).to.be.equal('Tail'); expect(typeof invokeStub.args[0][2].Payload).to.not.be.equal('undefined'); - awsInvoke.aws.request.restore(); + awsInvoke.provider.request.restore(); }); }); @@ -185,7 +185,7 @@ describe('AwsInvoke', () => { expect(invokeStub.args[0][2].InvocationType).to.be.equal('OtherType'); expect(invokeStub.args[0][2].LogType).to.be.equal('None'); expect(typeof invokeStub.args[0][2].Payload).to.not.be.equal('undefined'); - awsInvoke.aws.request.restore(); + awsInvoke.provider.request.restore(); }); }); }); diff --git a/lib/plugins/aws/lib/monitorStack.js b/lib/plugins/aws/lib/monitorStack.js index 2ef93e6db..8d08aa96f 100644 --- a/lib/plugins/aws/lib/monitorStack.js +++ b/lib/plugins/aws/lib/monitorStack.js @@ -35,7 +35,7 @@ module.exports = { const params = { StackName: cfData.StackId, }; - return this.aws.request('CloudFormation', + return this.provider.request('CloudFormation', 'describeStackEvents', params, this.options.stage, diff --git a/lib/plugins/aws/logs/index.js b/lib/plugins/aws/logs/index.js index 750c3b490..0e1779691 100644 --- a/lib/plugins/aws/logs/index.js +++ b/lib/plugins/aws/logs/index.js @@ -11,8 +11,7 @@ class AwsLogs { constructor(serverless, options) { this.serverless = serverless; this.options = options || {}; - this.provider = 'aws'; - this.aws = this.serverless.getProvider(this.provider); + this.provider = this.serverless.getProvider('aws'); Object.assign(this, validate); @@ -44,7 +43,7 @@ class AwsLogs { orderBy: 'LastEventTime', }; - return this.aws + return this.provider .request('CloudWatchLogs', 'describeLogStreams', params, @@ -119,7 +118,7 @@ class AwsLogs { } } - return this.aws + return this.provider .request('CloudWatchLogs', 'filterLogEvents', params, diff --git a/lib/plugins/aws/logs/tests/index.js b/lib/plugins/aws/logs/tests/index.js index 651ca6c7c..d718c80a5 100644 --- a/lib/plugins/aws/logs/tests/index.js +++ b/lib/plugins/aws/logs/tests/index.js @@ -31,8 +31,8 @@ describe('AwsLogs', () => { expect(awsLogsWithEmptyOptions.options).to.deep.equal({}); }); - it('should set the provider variable to "aws"', () => expect(awsLogs.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsLogs.provider).to.be.instanceof(AwsProvider)); it('should run promise chain in order', () => { const validateStub = sinon @@ -116,7 +116,7 @@ describe('AwsLogs', () => { }, ], }; - const getLogStreamsStub = sinon.stub(awsLogs.aws, 'request').returns( + const getLogStreamsStub = sinon.stub(awsLogs.provider, 'request').returns( BbPromise.resolve(replyMock) ); @@ -139,20 +139,20 @@ describe('AwsLogs', () => { expect(logStreamNames[1]) .to.be.equal('2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba'); - awsLogs.aws.request.restore(); + awsLogs.provider.request.restore(); }); }); it('should throw error if no log streams found', () => { - sinon.stub(awsLogs.aws, 'request').returns(BbPromise.resolve()); + sinon.stub(awsLogs.provider, 'request').returns(BbPromise.resolve()); return awsLogs.getLogStreams() .then(() => { expect(1).to.equal(2); - awsLogs.aws.request.restore(); + awsLogs.provider.request.restore(); }).catch(e => { expect(e.name).to.be.equal('ServerlessError'); - awsLogs.aws.request.restore(); + awsLogs.provider.request.restore(); }); }); }); @@ -177,7 +177,7 @@ describe('AwsLogs', () => { '2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba', '2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba', ]; - const filterLogEventsStub = sinon.stub(awsLogs.aws, 'request').returns( + const filterLogEventsStub = sinon.stub(awsLogs.provider, 'request').returns( BbPromise.resolve(replyMock) ); awsLogs.serverless.service.service = 'new-service'; @@ -203,7 +203,7 @@ describe('AwsLogs', () => { expect(filterLogEventsStub.args[0][2].logStreamNames).to.deep.equal(logStreamNamesMock); expect(filterLogEventsStub.args[0][2].filterPattern).to.be.equal('error'); expect(typeof filterLogEventsStub.args[0][2].startTime).to.be.equal('number'); - awsLogs.aws.request.restore(); + awsLogs.provider.request.restore(); }); }); @@ -226,7 +226,7 @@ describe('AwsLogs', () => { '2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba', '2016/07/28/[$LATEST]83f5206ab2a8488290349b9c1fbfe2ba', ]; - const filterLogEventsStub = sinon.stub(awsLogs.aws, 'request').returns( + const filterLogEventsStub = sinon.stub(awsLogs.provider, 'request').returns( BbPromise.resolve(replyMock) ); awsLogs.serverless.service.service = 'new-service'; @@ -252,7 +252,7 @@ describe('AwsLogs', () => { expect(filterLogEventsStub.args[0][2].logStreamNames).to.deep.equal(logStreamNamesMock); expect(filterLogEventsStub.args[0][2].filterPattern).to.be.equal('error'); expect(typeof filterLogEventsStub.args[0][2].startTime).to.be.equal('number'); - awsLogs.aws.request.restore(); + awsLogs.provider.request.restore(); }); }); }); diff --git a/lib/plugins/aws/remove/index.js b/lib/plugins/aws/remove/index.js index a7aa02005..e7ca3ca5b 100644 --- a/lib/plugins/aws/remove/index.js +++ b/lib/plugins/aws/remove/index.js @@ -10,8 +10,7 @@ class AwsRemove { constructor(serverless, options) { this.serverless = serverless; this.options = options || {}; - this.provider = 'aws'; - this.aws = this.serverless.getProvider(this.provider); + this.provider = this.serverless.getProvider('aws'); Object.assign(this, validate, emptyS3Bucket, removeStack, monitorStack); diff --git a/lib/plugins/aws/remove/lib/bucket.js b/lib/plugins/aws/remove/lib/bucket.js index e96b41dae..b20f7b755 100644 --- a/lib/plugins/aws/remove/lib/bucket.js +++ b/lib/plugins/aws/remove/lib/bucket.js @@ -4,7 +4,7 @@ const BbPromise = require('bluebird'); module.exports = { setServerlessDeploymentBucketName() { - return this.aws.getServerlessDeploymentBucketName(this.options.stage, this.options.region) + return this.provider.getServerlessDeploymentBucketName(this.options.stage, this.options.region) .then((bucketName) => { this.bucketName = bucketName; }); @@ -15,7 +15,7 @@ module.exports = { this.serverless.cli.log('Getting all objects in S3 bucket...'); const serviceStage = `${this.serverless.service.service}/${this.options.stage}`; - return this.aws.request('S3', 'listObjectsV2', { + return this.provider.request('S3', 'listObjectsV2', { Bucket: this.bucketName, Prefix: `serverless/${serviceStage}`, }, this.options.stage, this.options.region).then((result) => { @@ -33,7 +33,7 @@ module.exports = { deleteObjects() { this.serverless.cli.log('Removing objects in S3 bucket...'); if (this.objectsInBucket.length) { - return this.aws.request('S3', 'deleteObjects', { + return this.provider.request('S3', 'deleteObjects', { Bucket: this.bucketName, Delete: { Objects: this.objectsInBucket, diff --git a/lib/plugins/aws/remove/lib/stack.js b/lib/plugins/aws/remove/lib/stack.js index a6c151c9f..243dd4e2a 100644 --- a/lib/plugins/aws/remove/lib/stack.js +++ b/lib/plugins/aws/remove/lib/stack.js @@ -13,7 +13,7 @@ module.exports = { StackId: stackName, }; - return this.aws.request('CloudFormation', + return this.provider.request('CloudFormation', 'deleteStack', params, this.options.stage, diff --git a/lib/plugins/aws/remove/tests/bucket.js b/lib/plugins/aws/remove/tests/bucket.js index 2423f4943..e92ec5df4 100644 --- a/lib/plugins/aws/remove/tests/bucket.js +++ b/lib/plugins/aws/remove/tests/bucket.js @@ -25,7 +25,7 @@ describe('emptyS3Bucket', () => { describe('#setServerlessDeploymentBucketName()', () => { it('should store the name of the Serverless deployment bucket in the "this" variable', () => { const getServerlessDeploymentBucketNameStub = sinon - .stub(awsRemove.aws, 'getServerlessDeploymentBucketName') + .stub(awsRemove.provider, 'getServerlessDeploymentBucketName') .returns(BbPromise.resolve('new-service-dev-us-east-1-12345678')); return awsRemove.setServerlessDeploymentBucketName().then(() => { @@ -33,14 +33,14 @@ describe('emptyS3Bucket', () => { expect(getServerlessDeploymentBucketNameStub.calledOnce).to.be.equal(true); expect(getServerlessDeploymentBucketNameStub .calledWith(awsRemove.options.stage, awsRemove.options.region)); - awsRemove.aws.getServerlessDeploymentBucketName.restore(); + awsRemove.provider.getServerlessDeploymentBucketName.restore(); }); }); }); describe('#listObjects()', () => { it('should resolve if no objects are present', () => { - const listObjectsStub = sinon.stub(awsRemove.aws, 'request') + const listObjectsStub = sinon.stub(awsRemove.provider, 'request') .returns(BbPromise.resolve()); return awsRemove.listObjects().then(() => { @@ -51,12 +51,12 @@ describe('emptyS3Bucket', () => { expect(listObjectsStub.args[0][2].Bucket) .to.be.equal(awsRemove.bucketName); expect(awsRemove.objectsInBucket.length).to.equal(0); - awsRemove.aws.request.restore(); + awsRemove.provider.request.restore(); }); }); it('should push objects to the array if present', () => { - const listObjectsStub = sinon.stub(awsRemove.aws, 'request') + const listObjectsStub = sinon.stub(awsRemove.provider, 'request') .returns(BbPromise.resolve({ Contents: [ { Key: 'object1' }, @@ -73,7 +73,7 @@ describe('emptyS3Bucket', () => { .to.be.equal(awsRemove.bucketName); expect(awsRemove.objectsInBucket[0]).to.deep.equal({ Key: 'object1' }); expect(awsRemove.objectsInBucket[1]).to.deep.equal({ Key: 'object2' }); - awsRemove.aws.request.restore(); + awsRemove.provider.request.restore(); }); }); }); @@ -82,7 +82,7 @@ describe('emptyS3Bucket', () => { it('should delete all objects in the S3 bucket', () => { awsRemove.objectsInBucket = [{ Key: 'foo' }]; - const deleteObjectsStub = sinon.stub(awsRemove.aws, 'request') + const deleteObjectsStub = sinon.stub(awsRemove.provider, 'request') .returns(BbPromise.resolve()); return awsRemove.deleteObjects().then(() => { @@ -92,7 +92,7 @@ describe('emptyS3Bucket', () => { .to.be.equal(awsRemove.bucketName); expect(deleteObjectsStub.args[0][2].Delete.Objects) .to.be.equal(awsRemove.objectsInBucket); - awsRemove.aws.request.restore(); + awsRemove.provider.request.restore(); }); }); diff --git a/lib/plugins/aws/remove/tests/index.js b/lib/plugins/aws/remove/tests/index.js index 6a725aa27..8dacceb58 100644 --- a/lib/plugins/aws/remove/tests/index.js +++ b/lib/plugins/aws/remove/tests/index.js @@ -3,7 +3,8 @@ const expect = require('chai').expect; const BbPromise = require('bluebird'); const sinon = require('sinon'); -const AwsRemove = require('../'); +const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsRemove = require('../index'); const Serverless = require('../../../../Serverless'); describe('AwsRemove', () => { @@ -12,14 +13,15 @@ describe('AwsRemove', () => { stage: 'dev', region: 'us-east-1', }; + serverless.setProvider('aws', new AwsProvider(serverless)); const awsRemove = new AwsRemove(serverless, options); awsRemove.serverless.cli = new serverless.classes.CLI(); describe('#constructor()', () => { it('should have hooks', () => expect(awsRemove.hooks).to.be.not.empty); - it('should set the provider variable to "aws"', () => expect(awsRemove.provider) - .to.equal('aws')); + it('should set the provider variable to an instance of AwsProvider', () => + expect(awsRemove.provider).to.be.instanceof(AwsProvider)); it('should have access to the serverless instance', () => { expect(awsRemove.serverless).to.deep.equal(serverless); diff --git a/lib/plugins/aws/remove/tests/stack.js b/lib/plugins/aws/remove/tests/stack.js index 996352cd2..0e5b1deb6 100644 --- a/lib/plugins/aws/remove/tests/stack.js +++ b/lib/plugins/aws/remove/tests/stack.js @@ -25,12 +25,12 @@ describe('removeStack', () => { describe('#remove()', () => { it('should remove a stack', () => { const removeStackStub = sinon - .stub(awsRemove.aws, 'request').returns(BbPromise.resolve()); + .stub(awsRemove.provider, 'request').returns(BbPromise.resolve()); return awsRemove.remove().then(() => { expect(removeStackStub.calledOnce).to.be.equal(true); expect(removeStackStub.calledWith(awsRemove.options.stage, awsRemove.options.region)); - awsRemove.aws.request.restore(); + awsRemove.provider.request.restore(); }); }); }); diff --git a/lib/plugins/aws/tests/monitorStack.js b/lib/plugins/aws/tests/monitorStack.js index 2c6e2fcbf..06d5c4244 100644 --- a/lib/plugins/aws/tests/monitorStack.js +++ b/lib/plugins/aws/tests/monitorStack.js @@ -14,7 +14,7 @@ describe('monitorStack', () => { beforeEach(() => { awsPlugin.serverless = serverless; - awsPlugin.aws = new AwsProvider(serverless); + awsPlugin.provider = new AwsProvider(serverless); awsPlugin.serverless.cli = new CLI(serverless); awsPlugin.options = { stage: 'dev', @@ -27,28 +27,28 @@ describe('monitorStack', () => { describe('#monitorStack()', () => { it('should skip monitoring if the --noDeploy option is specified', () => { awsPlugin.options.noDeploy = true; - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; return awsPlugin.monitorStack('update', cfDataMock, 10).then(() => { expect(describeStackEventsStub.callCount).to.be.equal(0); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); it('should skip monitoring if the stack was already created', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); return awsPlugin.monitorStack('update', 'alreadyCreated', 10).then(() => { expect(describeStackEventsStub.callCount).to.be.equal(0); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); it('should keep monitoring until CREATE_COMPLETE stack status', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -87,12 +87,12 @@ describe('monitorStack', () => { awsPlugin.options.region )); expect(stackStatus).to.be.equal('CREATE_COMPLETE'); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); it('should keep monitoring until UPDATE_COMPLETE stack status', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -131,12 +131,12 @@ describe('monitorStack', () => { awsPlugin.options.region )); expect(stackStatus).to.be.equal('UPDATE_COMPLETE'); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); it('should keep monitoring until DELETE_COMPLETE stack status', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -175,12 +175,12 @@ describe('monitorStack', () => { awsPlugin.options.region )); expect(stackStatus).to.be.equal('DELETE_COMPLETE'); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); it('should keep monitoring until DELETE_COMPLETE or stack not found catch', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -211,13 +211,13 @@ describe('monitorStack', () => { awsPlugin.options.region )); expect(stackStatus).to.be.equal('DELETE_COMPLETE'); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); it('should output all stack events information with the --verbose option', () => { awsPlugin.options.verbose = true; - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -283,12 +283,12 @@ describe('monitorStack', () => { awsPlugin.options.stage, awsPlugin.options.region )); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); it('should catch describeStackEvents error if stack was not in deleting state', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -307,12 +307,12 @@ describe('monitorStack', () => { awsPlugin.options.stage, awsPlugin.options.region )); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); it('should throw an error and exit immediataley if statck status is *_FAILED', () => { - const describeStackEventsStub = sinon.stub(awsPlugin.aws, 'request'); + const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request'); const cfDataMock = { StackId: 'new-service-dev', }; @@ -380,7 +380,7 @@ describe('monitorStack', () => { awsPlugin.options.stage, awsPlugin.options.region )); - awsPlugin.aws.request.restore(); + awsPlugin.provider.request.restore(); }); }); }); diff --git a/tests/classes/PluginManager.js b/tests/classes/PluginManager.js index 47ce9516c..aaa49c08e 100644 --- a/tests/classes/PluginManager.js +++ b/tests/classes/PluginManager.js @@ -273,7 +273,7 @@ describe('PluginManager', () => { it('should add a plugin instance to the plugins array', () => { pluginManager.addPlugin(SynchronousPluginMock); - expect(pluginManager.plugins[0]).to.be.an.instanceof(SynchronousPluginMock); + expect(pluginManager.plugins[0]).to.be.instanceof(SynchronousPluginMock); }); it('should load the plugin commands', () => { From 25b233137f2710e9f879e4f969fa17021e01e2fa Mon Sep 17 00:00:00 2001 From: Philipp Muens Date: Fri, 14 Oct 2016 21:50:03 -0700 Subject: [PATCH 5/8] Move class tests into classes directory --- tests/classes/CLI.js => lib/classes/CLI.test.js | 0 .../Config.js => lib/classes/Config.test.js | 0 .../classes/PluginManager.test.js | 0 .../Service.js => lib/classes/Service.test.js | 0 .../classes/Utils.js => lib/classes/Utils.test.js | 0 .../Variables.js => lib/classes/Variables.test.js | 2 +- .../classes/YamlParser.test.js | 0 tests/all.js | 14 +++++++------- 8 files changed, 8 insertions(+), 8 deletions(-) rename tests/classes/CLI.js => lib/classes/CLI.test.js (100%) rename tests/classes/Config.js => lib/classes/Config.test.js (100%) rename tests/classes/PluginManager.js => lib/classes/PluginManager.test.js (100%) rename tests/classes/Service.js => lib/classes/Service.test.js (100%) rename tests/classes/Utils.js => lib/classes/Utils.test.js (100%) rename tests/classes/Variables.js => lib/classes/Variables.test.js (99%) rename tests/classes/YamlParser.js => lib/classes/YamlParser.test.js (100%) diff --git a/tests/classes/CLI.js b/lib/classes/CLI.test.js similarity index 100% rename from tests/classes/CLI.js rename to lib/classes/CLI.test.js diff --git a/tests/classes/Config.js b/lib/classes/Config.test.js similarity index 100% rename from tests/classes/Config.js rename to lib/classes/Config.test.js diff --git a/tests/classes/PluginManager.js b/lib/classes/PluginManager.test.js similarity index 100% rename from tests/classes/PluginManager.js rename to lib/classes/PluginManager.test.js diff --git a/tests/classes/Service.js b/lib/classes/Service.test.js similarity index 100% rename from tests/classes/Service.js rename to lib/classes/Service.test.js diff --git a/tests/classes/Utils.js b/lib/classes/Utils.test.js similarity index 100% rename from tests/classes/Utils.js rename to lib/classes/Utils.test.js diff --git a/tests/classes/Variables.js b/lib/classes/Variables.test.js similarity index 99% rename from tests/classes/Variables.js rename to lib/classes/Variables.test.js index 15e303920..bfef5ecd2 100644 --- a/tests/classes/Variables.js +++ b/lib/classes/Variables.test.js @@ -7,7 +7,7 @@ const Variables = require('../../lib/classes/Variables'); const Utils = require('../../lib/classes/Utils'); const Serverless = require('../../lib/Serverless'); const sinon = require('sinon'); -const testUtils = require('../utils'); +const testUtils = require('../../tests/utils'); describe('Variables', () => { describe('#constructor()', () => { diff --git a/tests/classes/YamlParser.js b/lib/classes/YamlParser.test.js similarity index 100% rename from tests/classes/YamlParser.js rename to lib/classes/YamlParser.test.js diff --git a/tests/all.js b/tests/all.js index 0880e686c..547a0abda 100644 --- a/tests/all.js +++ b/tests/all.js @@ -2,13 +2,13 @@ // Serverless Core Tests require('../lib/Serverless.test'); -require('./classes/PluginManager'); -require('./classes/Utils'); -require('./classes/Config'); -require('./classes/Service'); -require('./classes/Variables'); -require('./classes/YamlParser'); -require('./classes/CLI'); +require('../lib/classes/PluginManager.test'); +require('../lib/classes/Utils.test'); +require('../lib/classes/Config.test'); +require('../lib/classes/Service.test'); +require('../lib/classes/Variables.test'); +require('../lib/classes/YamlParser.test'); +require('../lib/classes/CLI.test'); // Core Plugins Tests require('../lib/plugins/create/tests/create'); From a08c4d5cc4aca515d300e2caf3741554f61ce8f0 Mon Sep 17 00:00:00 2001 From: Philipp Muens Date: Fri, 14 Oct 2016 22:09:42 -0700 Subject: [PATCH 6/8] Remove *.test files from test coverage --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 33a4947a8..3b8027879 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "sls": "./bin/serverless" }, "scripts": { - "test": "istanbul cover node_modules/mocha/bin/_mocha tests/all -- -R spec --recursive", + "test": "istanbul cover -x '**/*.test.js' node_modules/mocha/bin/_mocha tests/all -- -R spec --recursive", "lint": "eslint .", "simple-integration-test": "mocha tests/integration/simple-integration-test", "complex-integration-test": "mocha tests/integration/all" From c273abec685652c3dfeefb6c80c9d5f6afe90440 Mon Sep 17 00:00:00 2001 From: Philipp Muens Date: Wed, 19 Oct 2016 08:31:53 +0200 Subject: [PATCH 7/8] Move AwsProvider plugin into aws directory --- lib/plugins/Plugins.json | 2 +- lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js | 2 +- lib/plugins/aws/deploy/compile/events/s3/tests/index.js | 2 +- lib/plugins/aws/deploy/compile/events/schedule/tests/index.js | 2 +- lib/plugins/aws/deploy/compile/events/sns/tests/index.js | 2 +- lib/plugins/aws/deploy/compile/events/stream/tests/index.js | 2 +- lib/plugins/aws/deploy/compile/functions/tests/index.js | 2 +- lib/plugins/aws/deploy/tests/cleanupS3Bucket.js | 2 +- lib/plugins/aws/deploy/tests/configureStack.js | 2 +- lib/plugins/aws/deploy/tests/createStack.js | 2 +- lib/plugins/aws/deploy/tests/index.js | 2 +- lib/plugins/aws/deploy/tests/setBucketName.js | 2 +- lib/plugins/aws/deploy/tests/updateStack.js | 2 +- lib/plugins/aws/deploy/tests/uploadArtifacts.js | 2 +- lib/plugins/aws/deployFunction/tests/index.js | 2 +- lib/plugins/aws/info/tests/index.js | 2 +- lib/plugins/aws/invoke/tests/index.js | 2 +- lib/plugins/aws/logs/tests/index.js | 2 +- lib/plugins/{awsProvider => aws/provider}/awsProvider.js | 0 lib/plugins/{awsProvider => aws/provider}/awsProvider.test.js | 2 +- lib/plugins/aws/remove/tests/bucket.js | 2 +- lib/plugins/aws/remove/tests/index.js | 2 +- lib/plugins/aws/remove/tests/stack.js | 2 +- lib/plugins/aws/tests/monitorStack.js | 2 +- tests/all.js | 2 +- 25 files changed, 24 insertions(+), 24 deletions(-) rename lib/plugins/{awsProvider => aws/provider}/awsProvider.js (100%) rename lib/plugins/{awsProvider => aws/provider}/awsProvider.test.js (99%) diff --git a/lib/plugins/Plugins.json b/lib/plugins/Plugins.json index b9eecedf4..d213b41e7 100644 --- a/lib/plugins/Plugins.json +++ b/lib/plugins/Plugins.json @@ -9,7 +9,7 @@ "./logs/logs.js", "./remove/remove.js", "./slstats/slstats.js", - "./awsProvider/awsProvider.js", + "./aws/provider/awsProvider.js", "./aws/deploy/index.js", "./aws/invoke/index.js", "./aws/info/index.js", diff --git a/lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js b/lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js index 7237ea822..b4dc4183e 100644 --- a/lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/apiGateway/tests/index.js @@ -3,7 +3,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const BbPromise = require('bluebird'); -const AwsProvider = require('../../../../../../awsProvider/awsProvider'); +const AwsProvider = require('../../../../../provider/awsProvider'); const AwsCompileApigEvents = require('../index'); const Serverless = require('../../../../../../../Serverless'); diff --git a/lib/plugins/aws/deploy/compile/events/s3/tests/index.js b/lib/plugins/aws/deploy/compile/events/s3/tests/index.js index 62ebf2dc0..cf33a0a29 100644 --- a/lib/plugins/aws/deploy/compile/events/s3/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/s3/tests/index.js @@ -1,7 +1,7 @@ 'use strict'; const expect = require('chai').expect; -const AwsProvider = require('../../../../../../awsProvider/awsProvider'); +const AwsProvider = require('../../../../../provider/awsProvider'); const AwsCompileS3Events = require('../index'); const Serverless = require('../../../../../../../Serverless'); diff --git a/lib/plugins/aws/deploy/compile/events/schedule/tests/index.js b/lib/plugins/aws/deploy/compile/events/schedule/tests/index.js index b11882bc3..633435650 100644 --- a/lib/plugins/aws/deploy/compile/events/schedule/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/schedule/tests/index.js @@ -1,7 +1,7 @@ 'use strict'; const expect = require('chai').expect; -const AwsProvider = require('../../../../../../awsProvider/awsProvider'); +const AwsProvider = require('../../../../../provider/awsProvider'); const AwsCompileScheduledEvents = require('../index'); const Serverless = require('../../../../../../../Serverless'); diff --git a/lib/plugins/aws/deploy/compile/events/sns/tests/index.js b/lib/plugins/aws/deploy/compile/events/sns/tests/index.js index 295c0e883..a0807480d 100644 --- a/lib/plugins/aws/deploy/compile/events/sns/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/sns/tests/index.js @@ -1,7 +1,7 @@ 'use strict'; const expect = require('chai').expect; -const AwsProvider = require('../../../../../../awsProvider/awsProvider'); +const AwsProvider = require('../../../../../provider/awsProvider'); const AwsCompileSNSEvents = require('../index'); const Serverless = require('../../../../../../../Serverless'); diff --git a/lib/plugins/aws/deploy/compile/events/stream/tests/index.js b/lib/plugins/aws/deploy/compile/events/stream/tests/index.js index 873c38033..9b1f03ac9 100644 --- a/lib/plugins/aws/deploy/compile/events/stream/tests/index.js +++ b/lib/plugins/aws/deploy/compile/events/stream/tests/index.js @@ -1,7 +1,7 @@ 'use strict'; const expect = require('chai').expect; -const AwsProvider = require('../../../../../../awsProvider/awsProvider'); +const AwsProvider = require('../../../../../provider/awsProvider'); const AwsCompileStreamEvents = require('../index'); const Serverless = require('../../../../../../../Serverless'); diff --git a/lib/plugins/aws/deploy/compile/functions/tests/index.js b/lib/plugins/aws/deploy/compile/functions/tests/index.js index 395da587a..893b0fbd5 100644 --- a/lib/plugins/aws/deploy/compile/functions/tests/index.js +++ b/lib/plugins/aws/deploy/compile/functions/tests/index.js @@ -2,7 +2,7 @@ const path = require('path'); const expect = require('chai').expect; -const AwsProvider = require('../../../../../awsProvider/awsProvider'); +const AwsProvider = require('../../../../provider/awsProvider'); const AwsCompileFunctions = require('../index'); const Serverless = require('../../../../../../Serverless'); diff --git a/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js b/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js index 7cb72b387..0352fbfc6 100644 --- a/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js +++ b/lib/plugins/aws/deploy/tests/cleanupS3Bucket.js @@ -3,7 +3,7 @@ const sinon = require('sinon'); const BbPromise = require('bluebird'); const expect = require('chai').expect; -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); diff --git a/lib/plugins/aws/deploy/tests/configureStack.js b/lib/plugins/aws/deploy/tests/configureStack.js index 3eae9ce9c..386044c25 100644 --- a/lib/plugins/aws/deploy/tests/configureStack.js +++ b/lib/plugins/aws/deploy/tests/configureStack.js @@ -4,7 +4,7 @@ const sinon = require('sinon'); const BbPromise = require('bluebird'); const path = require('path'); const expect = require('chai').expect; -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const Serverless = require('../../../../Serverless'); const validate = require('../../lib/validate'); const configureStack = require('../lib/configureStack'); diff --git a/lib/plugins/aws/deploy/tests/createStack.js b/lib/plugins/aws/deploy/tests/createStack.js index 463369602..69970f657 100644 --- a/lib/plugins/aws/deploy/tests/createStack.js +++ b/lib/plugins/aws/deploy/tests/createStack.js @@ -4,7 +4,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const path = require('path'); const BbPromise = require('bluebird'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const testUtils = require('../../../../../tests/utils'); diff --git a/lib/plugins/aws/deploy/tests/index.js b/lib/plugins/aws/deploy/tests/index.js index af38cab45..8f67b8dce 100644 --- a/lib/plugins/aws/deploy/tests/index.js +++ b/lib/plugins/aws/deploy/tests/index.js @@ -1,6 +1,6 @@ 'use strict'; -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const expect = require('chai').expect; diff --git a/lib/plugins/aws/deploy/tests/setBucketName.js b/lib/plugins/aws/deploy/tests/setBucketName.js index d1c75950a..0cc069327 100644 --- a/lib/plugins/aws/deploy/tests/setBucketName.js +++ b/lib/plugins/aws/deploy/tests/setBucketName.js @@ -2,7 +2,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); diff --git a/lib/plugins/aws/deploy/tests/updateStack.js b/lib/plugins/aws/deploy/tests/updateStack.js index 9d9046b77..199368aef 100644 --- a/lib/plugins/aws/deploy/tests/updateStack.js +++ b/lib/plugins/aws/deploy/tests/updateStack.js @@ -4,7 +4,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const path = require('path'); const BbPromise = require('bluebird'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const testUtils = require('../../../../../tests/utils'); diff --git a/lib/plugins/aws/deploy/tests/uploadArtifacts.js b/lib/plugins/aws/deploy/tests/uploadArtifacts.js index 1b1548c82..146af269d 100644 --- a/lib/plugins/aws/deploy/tests/uploadArtifacts.js +++ b/lib/plugins/aws/deploy/tests/uploadArtifacts.js @@ -4,7 +4,7 @@ const sinon = require('sinon'); const path = require('path'); const BbPromise = require('bluebird'); const expect = require('chai').expect; -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsDeploy = require('../index'); const Serverless = require('../../../../Serverless'); const testUtils = require('../../../../../tests/utils'); diff --git a/lib/plugins/aws/deployFunction/tests/index.js b/lib/plugins/aws/deployFunction/tests/index.js index 3d0650921..d1489d7cb 100644 --- a/lib/plugins/aws/deployFunction/tests/index.js +++ b/lib/plugins/aws/deployFunction/tests/index.js @@ -5,7 +5,7 @@ const sinon = require('sinon'); const path = require('path'); const fs = require('fs'); const Package = require('../../../package'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsDeployFunction = require('../index'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); diff --git a/lib/plugins/aws/info/tests/index.js b/lib/plugins/aws/info/tests/index.js index 8eeb97837..f12d45f8f 100644 --- a/lib/plugins/aws/info/tests/index.js +++ b/lib/plugins/aws/info/tests/index.js @@ -3,7 +3,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const AwsInfo = require('../'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const Serverless = require('../../../../Serverless'); const CLI = require('../../../../classes/CLI'); const BbPromise = require('bluebird'); diff --git a/lib/plugins/aws/invoke/tests/index.js b/lib/plugins/aws/invoke/tests/index.js index 3f1f2c8bf..381f24aee 100644 --- a/lib/plugins/aws/invoke/tests/index.js +++ b/lib/plugins/aws/invoke/tests/index.js @@ -4,7 +4,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const path = require('path'); const AwsInvoke = require('../'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); const testUtils = require('../../../../../tests/utils'); diff --git a/lib/plugins/aws/logs/tests/index.js b/lib/plugins/aws/logs/tests/index.js index d718c80a5..e193315a5 100644 --- a/lib/plugins/aws/logs/tests/index.js +++ b/lib/plugins/aws/logs/tests/index.js @@ -2,7 +2,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsLogs = require('../'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); diff --git a/lib/plugins/awsProvider/awsProvider.js b/lib/plugins/aws/provider/awsProvider.js similarity index 100% rename from lib/plugins/awsProvider/awsProvider.js rename to lib/plugins/aws/provider/awsProvider.js diff --git a/lib/plugins/awsProvider/awsProvider.test.js b/lib/plugins/aws/provider/awsProvider.test.js similarity index 99% rename from lib/plugins/awsProvider/awsProvider.test.js rename to lib/plugins/aws/provider/awsProvider.test.js index 8dde002d4..e4b9370f0 100644 --- a/lib/plugins/awsProvider/awsProvider.test.js +++ b/lib/plugins/aws/provider/awsProvider.test.js @@ -3,7 +3,7 @@ const sinon = require('sinon'); const BbPromise = require('bluebird'); const expect = require('chai').expect; -const Serverless = require('../../Serverless'); +const Serverless = require('../../../Serverless'); const AwsProvider = require('./awsProvider'); const proxyquire = require('proxyquire'); diff --git a/lib/plugins/aws/remove/tests/bucket.js b/lib/plugins/aws/remove/tests/bucket.js index e92ec5df4..a06593d0c 100644 --- a/lib/plugins/aws/remove/tests/bucket.js +++ b/lib/plugins/aws/remove/tests/bucket.js @@ -2,7 +2,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsRemove = require('../index'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); diff --git a/lib/plugins/aws/remove/tests/index.js b/lib/plugins/aws/remove/tests/index.js index 8dacceb58..db6543ea7 100644 --- a/lib/plugins/aws/remove/tests/index.js +++ b/lib/plugins/aws/remove/tests/index.js @@ -3,7 +3,7 @@ const expect = require('chai').expect; const BbPromise = require('bluebird'); const sinon = require('sinon'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsRemove = require('../index'); const Serverless = require('../../../../Serverless'); diff --git a/lib/plugins/aws/remove/tests/stack.js b/lib/plugins/aws/remove/tests/stack.js index 0e5b1deb6..ddaa35640 100644 --- a/lib/plugins/aws/remove/tests/stack.js +++ b/lib/plugins/aws/remove/tests/stack.js @@ -2,7 +2,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); -const AwsProvider = require('../../../awsProvider/awsProvider'); +const AwsProvider = require('../../provider/awsProvider'); const AwsRemove = require('../index'); const Serverless = require('../../../../Serverless'); const BbPromise = require('bluebird'); diff --git a/lib/plugins/aws/tests/monitorStack.js b/lib/plugins/aws/tests/monitorStack.js index 06d5c4244..35a1fcf8d 100644 --- a/lib/plugins/aws/tests/monitorStack.js +++ b/lib/plugins/aws/tests/monitorStack.js @@ -4,7 +4,7 @@ const expect = require('chai').expect; const sinon = require('sinon'); const BbPromise = require('bluebird'); const Serverless = require('../../../Serverless'); -const AwsProvider = require('../../awsProvider/awsProvider'); +const AwsProvider = require('../provider/awsProvider'); const CLI = require('../../../classes/CLI'); const monitorStack = require('../lib/monitorStack'); diff --git a/tests/all.js b/tests/all.js index 547a0abda..0fcb26610 100644 --- a/tests/all.js +++ b/tests/all.js @@ -22,7 +22,7 @@ require('../lib/plugins/package/tests/all'); require('../lib/plugins/slstats/tests/slstats'); // AWS Plugins Tests -require('../lib/plugins/awsProvider/awsProvider.test'); +require('../lib/plugins/aws/provider/awsProvider.test'); require('../lib/plugins/aws/tests/validate'); require('../lib/plugins/aws/tests/monitorStack'); require('../lib/plugins/aws/info/tests'); From e4903067b11623031f7d5e236992952f6e1fe911 Mon Sep 17 00:00:00 2001 From: Philipp Muens Date: Wed, 19 Oct 2016 09:10:35 +0200 Subject: [PATCH 8/8] Add documentation for the new Provider pattern --- .../01-creating-plugins.md | 53 ++++++++++++++++++- .../02-creating-provider-plugins.md | 32 +++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/docs/04-extending-serverless/01-creating-plugins.md b/docs/04-extending-serverless/01-creating-plugins.md index 867ecb251..3c052ce5e 100644 --- a/docs/04-extending-serverless/01-creating-plugins.md +++ b/docs/04-extending-serverless/01-creating-plugins.md @@ -362,7 +362,11 @@ Plugins can be provider specific which means that they are bound to a provider. **Note:** Binding a plugin to a provider is optional. Serverless will always consider your plugin if you don't specify a `provider`. -The provider definition should be added inside the plugins constructor: +The provider definition should be added inside the plugins constructor and can be the name of the provider (as a string) or the provider plugin instance. + +### String representation + +The string representation simply tells Serverless that this plugin should only be loaded if the provider defined in the service matches the one of the plugin. ```javascript 'use strict'; @@ -402,7 +406,52 @@ class ProviderDeploy { module.exports = ProviderDeploy; ``` -The plugins functionality will now only be executed when the Serverless services provider matches the provider name which is defined inside the plugins constructor. +### The provider plugin instance + +If you want to get access to provider specific utilities such as the SDK you can get the provider plugin instance with the help of the +`this.serverless.getProvider('providerName')` function and set it to the plugins `provider` property. +You can access the wrapped methods via `this.provider.`. + +The usage of the plugins `provider` property will load the plugin only if the `provider` matches the one defined in the service. + +```javascript +'use strict'; + +class ProviderInvoke { + constructor(serverless, options) { + this.serverless = serverless; + this.options = options; + + // get access to the provider plugin instance here + this.provider = this.serverless.getProvider('providerName'); + + this.commands = { + invoke: { + lifecycleEvents: [ + 'function' + ], + options: { + function: { + usage: 'Specify the function you want to invoke (e.g. "--function myFunction")', + required: true + } + } + }, + }; + + this.hooks = { + 'invoke:function': this.invokeFunction.bind(this) + } + } + + invokeFunction() { + // use the "request" method from the provider plugin + return this.provider.request('function', 'invoke', this.options.function); + } +} + +module.exports = ProviderInvoke; +``` ## Plugin registration process diff --git a/docs/04-extending-serverless/02-creating-provider-plugins.md b/docs/04-extending-serverless/02-creating-provider-plugins.md index 6288424a8..ca11ca0f4 100644 --- a/docs/04-extending-serverless/02-creating-provider-plugins.md +++ b/docs/04-extending-serverless/02-creating-provider-plugins.md @@ -9,6 +9,38 @@ layout: Doc Integrating different infrastructure providers happens through the standard plugin system. Take a look at the ["building plugins"](./01-creating-plugins.md) documentation to understand how the plugin system works. +## Provider plugins + +We'd recommend that you encapsulate provider related utilities into an own plugin and call it `Provider`. +You can register this provider plugin in Serverless with the help of the `serverless.setProvider(, )` function. +Furthermore your provider plugin needs to provide a static method which returns the providers name. + +Here's a simple skeleton which shows this in detail and can be used as a boilerplate to get started: + +```javascript +class MyProvider { + static getProviderName() { + return 'providerName'; + } + + constructor(serverless) { + this.serverless = serverless; + this.sdk = TheProvidersSDK; + this.provider = this; // only load plugin in a "providerName" service context + this.serverless.setProvider('providerName', this); + } + + // this method can be easily re-used by other plugins + useSDK(command) { + return this.sdk(command); + } +} + +module.exports = MyProvider; +``` + +After doing this other plugins can simply call `this.serverless.getProvider('providerName')` and access all the methods you've defined in your provider plugin. + ## Provider specific plugins You can add the providers name inside the constructor of your plugin. This makes it possible to only execute your plugins logic when the Serverless service uses the provider you've specified in your plugin.