mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
Merge pull request #2431 from serverless/preparation-for-multi-provider-support
Preparation for multi provider support
This commit is contained in:
commit
079c4459cc
@ -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.<methodName>`.
|
||||
|
||||
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
|
||||
|
||||
|
||||
@ -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 `<ProviderName>Provider`.
|
||||
You can register this provider plugin in Serverless with the help of the `serverless.setProvider(<providerName>, <pluginInstance>)` 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.
|
||||
|
||||
@ -20,6 +20,8 @@ class Serverless {
|
||||
let configObject = config;
|
||||
configObject = configObject || {};
|
||||
|
||||
this.providers = {};
|
||||
|
||||
this.version = Version;
|
||||
|
||||
this.yamlParser = new YamlParser(this);
|
||||
@ -58,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);
|
||||
|
||||
@ -90,6 +88,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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
@ -106,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)
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
@ -32,8 +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.provider)) {
|
||||
if (pluginProvider
|
||||
&& (pluginProvider !== this.serverless.service.provider.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -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' };
|
||||
@ -286,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', () => {
|
||||
@ -294,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()', () => {
|
||||
@ -670,7 +702,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);
|
||||
@ -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()', () => {
|
||||
@ -9,6 +9,7 @@
|
||||
"./logs/logs.js",
|
||||
"./remove/remove.js",
|
||||
"./slstats/slstats.js",
|
||||
"./aws/provider/awsProvider.js",
|
||||
"./aws/deploy/index.js",
|
||||
"./aws/invoke/index.js",
|
||||
"./aws/info/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,
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const BbPromise = require('bluebird');
|
||||
const AwsProvider = require('../../../../../provider/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
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../../../../provider/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()', () => {
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../../../../provider/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()', () => {
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../../../../provider/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()', () => {
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../../../../provider/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()', () => {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
const path = require('path');
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../../../provider/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()', () => {
|
||||
|
||||
@ -12,14 +12,11 @@ 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.provider = this.serverless.getProvider('aws');
|
||||
|
||||
Object.assign(
|
||||
this,
|
||||
|
||||
@ -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.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.sdk.request('S3',
|
||||
return this.provider.request('S3',
|
||||
'deleteObjects',
|
||||
{
|
||||
Bucket: this.bucketName,
|
||||
|
||||
@ -79,7 +79,7 @@ module.exports = {
|
||||
if (bucketName) {
|
||||
return BbPromise.bind(this)
|
||||
.then(() => this.validateS3BucketName(bucketName))
|
||||
.then(() => this.sdk.request('S3',
|
||||
.then(() => this.provider.request('S3',
|
||||
'getBucketLocation',
|
||||
{
|
||||
Bucket: bucketName,
|
||||
|
||||
@ -27,7 +27,7 @@ module.exports = {
|
||||
Tags: Object.keys(stackTags).map((key) => ({ Key: key, Value: stackTags[key] })),
|
||||
};
|
||||
|
||||
return this.sdk.request('CloudFormation',
|
||||
return this.provider.request('CloudFormation',
|
||||
'createStack',
|
||||
params,
|
||||
this.options.stage,
|
||||
@ -55,7 +55,7 @@ module.exports = {
|
||||
return BbPromise.resolve();
|
||||
}
|
||||
|
||||
return this.sdk.request('CloudFormation',
|
||||
return this.provider.request('CloudFormation',
|
||||
'describeStackResources',
|
||||
{ StackName: stackName },
|
||||
this.options.stage,
|
||||
|
||||
@ -12,7 +12,7 @@ module.exports = {
|
||||
return BbPromise.resolve();
|
||||
}
|
||||
|
||||
return this.sdk.getServerlessDeploymentBucketName(this.options.stage, this.options.region)
|
||||
return this.provider.getServerlessDeploymentBucketName(this.options.stage, this.options.region)
|
||||
.then((bucketName) => {
|
||||
this.bucketName = bucketName;
|
||||
});
|
||||
|
||||
@ -39,7 +39,7 @@ module.exports = {
|
||||
});
|
||||
}
|
||||
|
||||
return this.sdk.request('CloudFormation',
|
||||
return this.provider.request('CloudFormation',
|
||||
'updateStack',
|
||||
params,
|
||||
this.options.stage,
|
||||
|
||||
@ -19,7 +19,7 @@ module.exports = {
|
||||
ContentType: 'application/json',
|
||||
};
|
||||
|
||||
return this.sdk.request('S3',
|
||||
return this.provider.request('S3',
|
||||
'putObject',
|
||||
params,
|
||||
this.options.stage,
|
||||
@ -42,7 +42,7 @@ module.exports = {
|
||||
ContentType: 'application/zip',
|
||||
};
|
||||
|
||||
return this.sdk.request('S3',
|
||||
return this.provider.request('S3',
|
||||
'putObject',
|
||||
params,
|
||||
this.options.stage,
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
const sinon = require('sinon');
|
||||
const BbPromise = require('bluebird');
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../provider/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.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@ -63,7 +65,7 @@ describe('cleanupS3Bucket', () => {
|
||||
};
|
||||
|
||||
const listObjectsStub = sinon
|
||||
.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve(serviceObjects));
|
||||
.stub(awsDeploy.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@ -121,7 +123,7 @@ describe('cleanupS3Bucket', () => {
|
||||
};
|
||||
|
||||
const listObjectsStub = sinon
|
||||
.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve(serviceObjects));
|
||||
.stub(awsDeploy.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@ -150,7 +152,7 @@ describe('cleanupS3Bucket', () => {
|
||||
};
|
||||
|
||||
const listObjectsStub = sinon
|
||||
.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve(serviceObjects));
|
||||
.stub(awsDeploy.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -170,13 +172,13 @@ describe('cleanupS3Bucket', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
deleteObjectsStub = sinon
|
||||
.stub(awsDeploy.sdk, '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.sdk.request.restore();
|
||||
awsDeploy.provider.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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -4,34 +4,37 @@ const sinon = require('sinon');
|
||||
const BbPromise = require('bluebird');
|
||||
const path = require('path');
|
||||
const expect = require('chai').expect;
|
||||
|
||||
const AwsProvider = require('../../provider/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.provider = 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.provider, '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.provider, '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.provider, '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);
|
||||
});
|
||||
|
||||
@ -4,6 +4,7 @@ const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const path = require('path');
|
||||
const BbPromise = require('bluebird');
|
||||
const AwsProvider = require('../../provider/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.provider, '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.provider, '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.provider.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.provider, '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.provider, '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.provider, '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.provider.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.provider, '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.provider, 'request').returns(BbPromise.reject(errorMock));
|
||||
|
||||
const createStub = sinon
|
||||
.stub(awsDeploy, 'create').returns(BbPromise.resolve());
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const AwsProvider = require('../../provider/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', () => {
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const AwsProvider = require('../../provider/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.provider, '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.provider.getServerlessDeploymentBucketName.restore();
|
||||
})
|
||||
);
|
||||
|
||||
@ -39,7 +41,7 @@ describe('#setBucketName()', () => {
|
||||
|
||||
return awsDeploy.setBucketName().then(() => {
|
||||
expect(getServerlessDeploymentBucketNameStub.calledOnce).to.be.equal(false);
|
||||
awsDeploy.sdk.getServerlessDeploymentBucketName.restore();
|
||||
awsDeploy.provider.getServerlessDeploymentBucketName.restore();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const path = require('path');
|
||||
const BbPromise = require('bluebird');
|
||||
const AwsProvider = require('../../provider/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.provider, '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.provider.request.restore();
|
||||
})
|
||||
);
|
||||
|
||||
@ -74,7 +76,7 @@ describe('updateStack', () => {
|
||||
.to.equal(
|
||||
'{"Statement":[{"Effect":"Allow","Principal":"*","Action":"Update:*","Resource":"*"}]}'
|
||||
);
|
||||
awsDeploy.sdk.request.restore();
|
||||
awsDeploy.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -4,6 +4,7 @@ const sinon = require('sinon');
|
||||
const path = require('path');
|
||||
const BbPromise = require('bluebird');
|
||||
const expect = require('chai').expect;
|
||||
const AwsProvider = require('../../provider/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.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#uploadZipFile()', () => {
|
||||
it('should throw for null artifact paths', () => {
|
||||
sinon.stub(awsDeploy.sdk, '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.sdk, 'request').returns(BbPromise.resolve());
|
||||
sinon.stub(awsDeploy.provider, '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.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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
|
||||
@ -12,8 +11,7 @@ class AwsDeployFunction {
|
||||
constructor(serverless, options) {
|
||||
this.serverless = serverless;
|
||||
this.options = options || {};
|
||||
this.provider = 'aws';
|
||||
this.sdk = new SDK(serverless);
|
||||
this.provider = this.serverless.getProvider('aws');
|
||||
|
||||
this.pkg = new Package(this.serverless, this.options);
|
||||
|
||||
@ -38,7 +36,7 @@ class AwsDeployFunction {
|
||||
FunctionName: this.options.functionObj.name,
|
||||
};
|
||||
|
||||
this.sdk.request(
|
||||
this.provider.request(
|
||||
'Lambda',
|
||||
'getFunction',
|
||||
params,
|
||||
@ -69,7 +67,7 @@ class AwsDeployFunction {
|
||||
ZipFile: data,
|
||||
};
|
||||
|
||||
return this.sdk.request(
|
||||
return this.provider.request(
|
||||
'Lambda',
|
||||
'updateFunctionCode',
|
||||
params,
|
||||
|
||||
@ -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('../../provider/awsProvider');
|
||||
const AwsDeployFunction = require('../index');
|
||||
const Serverless = require('../../../../Serverless');
|
||||
const BbPromise = require('bluebird');
|
||||
const testUtils = require('../../../../../tests/utils');
|
||||
@ -44,14 +45,15 @@ describe('AwsDeployFunction', () => {
|
||||
},
|
||||
};
|
||||
serverless.init();
|
||||
serverless.setProvider('aws', new AwsProvider(serverless));
|
||||
awsDeployFunction = new AwsDeployFunction(serverless, options);
|
||||
});
|
||||
|
||||
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);
|
||||
@ -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.provider, '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.provider.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.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,16 +2,14 @@
|
||||
|
||||
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.provider = this.serverless.getProvider('aws');
|
||||
this.options = options || {};
|
||||
this.provider = 'aws';
|
||||
this.sdk = new SDK(serverless);
|
||||
Object.assign(this, validate);
|
||||
|
||||
this.hooks = {
|
||||
@ -37,7 +35,7 @@ class AwsInfo {
|
||||
* Gather information about the service
|
||||
*/
|
||||
gather() {
|
||||
const stackName = this.sdk.getStackName(this.options.stage);
|
||||
const stackName = this.provider.getStackName(this.options.stage);
|
||||
const info = {
|
||||
service: this.serverless.service.service,
|
||||
stage: this.options.stage,
|
||||
@ -45,7 +43,7 @@ class AwsInfo {
|
||||
};
|
||||
|
||||
// Get info from CloudFormation Outputs
|
||||
return this.sdk.request('CloudFormation',
|
||||
return this.provider.request('CloudFormation',
|
||||
'describeStacks',
|
||||
{ StackName: stackName },
|
||||
this.options.stage,
|
||||
@ -113,7 +111,7 @@ class AwsInfo {
|
||||
const apiKeyNames = this.serverless.service.provider.apiKeys || [];
|
||||
|
||||
if (apiKeyNames.length) {
|
||||
return this.sdk.request('APIGateway',
|
||||
return this.provider.request('APIGateway',
|
||||
'getApiKeys',
|
||||
{ includeValues: true },
|
||||
this.options.stage,
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const AwsInfo = require('../');
|
||||
const AwsProvider = require('../../provider/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: [
|
||||
@ -41,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);
|
||||
@ -158,7 +160,7 @@ describe('AwsInfo', () => {
|
||||
],
|
||||
};
|
||||
|
||||
const describeStackStub = sinon.stub(awsInfo.sdk, 'request')
|
||||
const describeStackStub = sinon.stub(awsInfo.provider, '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.provider.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.provider.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.provider, '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.provider.request.restore();
|
||||
sinon.stub(awsInfo.provider, '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.provider.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.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.sdk.request.restore();
|
||||
awsInfo.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@ -317,14 +319,14 @@ describe('AwsInfo', () => {
|
||||
};
|
||||
|
||||
const getApiKeysStub = sinon
|
||||
.stub(awsInfo.sdk, '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.sdk.request.restore();
|
||||
awsInfo.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -11,8 +10,7 @@ class AwsInvoke {
|
||||
constructor(serverless, options) {
|
||||
this.serverless = serverless;
|
||||
this.options = options || {};
|
||||
this.provider = 'aws';
|
||||
this.sdk = new SDK(serverless);
|
||||
this.provider = this.serverless.getProvider('aws');
|
||||
|
||||
Object.assign(this, validate);
|
||||
|
||||
@ -58,7 +56,8 @@ 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.provider
|
||||
.request('Lambda', 'invoke', params, this.options.stage, this.options.region);
|
||||
}
|
||||
|
||||
log(invocationReply) {
|
||||
|
||||
@ -4,12 +4,14 @@ const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const path = require('path');
|
||||
const AwsInvoke = require('../');
|
||||
const AwsProvider = require('../../provider/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',
|
||||
@ -20,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
|
||||
@ -136,7 +138,7 @@ describe('AwsInvoke', () => {
|
||||
describe('#invoke()', () => {
|
||||
let invokeStub;
|
||||
beforeEach(() => {
|
||||
invokeStub = sinon.stub(awsInvoke.sdk, 'request').returns(BbPromise.resolve());
|
||||
invokeStub = sinon.stub(awsInvoke.provider, '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.provider.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.provider.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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -35,7 +35,7 @@ module.exports = {
|
||||
const params = {
|
||||
StackName: cfData.StackId,
|
||||
};
|
||||
return this.sdk.request('CloudFormation',
|
||||
return this.provider.request('CloudFormation',
|
||||
'describeStackEvents',
|
||||
params,
|
||||
this.options.stage,
|
||||
|
||||
@ -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');
|
||||
@ -12,8 +11,7 @@ class AwsLogs {
|
||||
constructor(serverless, options) {
|
||||
this.serverless = serverless;
|
||||
this.options = options || {};
|
||||
this.provider = 'aws';
|
||||
this.sdk = new SDK(serverless);
|
||||
this.provider = this.serverless.getProvider('aws');
|
||||
|
||||
Object.assign(this, validate);
|
||||
|
||||
@ -45,7 +43,7 @@ class AwsLogs {
|
||||
orderBy: 'LastEventTime',
|
||||
};
|
||||
|
||||
return this.sdk
|
||||
return this.provider
|
||||
.request('CloudWatchLogs',
|
||||
'describeLogStreams',
|
||||
params,
|
||||
@ -120,7 +118,7 @@ class AwsLogs {
|
||||
}
|
||||
}
|
||||
|
||||
return this.sdk
|
||||
return this.provider
|
||||
.request('CloudWatchLogs',
|
||||
'filterLogEvents',
|
||||
params,
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const AwsProvider = require('../../provider/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);
|
||||
});
|
||||
|
||||
@ -29,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
|
||||
@ -114,7 +116,7 @@ describe('AwsLogs', () => {
|
||||
},
|
||||
],
|
||||
};
|
||||
const getLogStreamsStub = sinon.stub(awsLogs.sdk, 'request').returns(
|
||||
const getLogStreamsStub = sinon.stub(awsLogs.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error if no log streams found', () => {
|
||||
sinon.stub(awsLogs.sdk, 'request').returns(BbPromise.resolve());
|
||||
sinon.stub(awsLogs.provider, 'request').returns(BbPromise.resolve());
|
||||
|
||||
return awsLogs.getLogStreams()
|
||||
.then(() => {
|
||||
expect(1).to.equal(2);
|
||||
awsLogs.sdk.request.restore();
|
||||
awsLogs.provider.request.restore();
|
||||
}).catch(e => {
|
||||
expect(e.name).to.be.equal('ServerlessError');
|
||||
awsLogs.sdk.request.restore();
|
||||
awsLogs.provider.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.provider, '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.provider.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.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -70,11 +70,16 @@ const impl = {
|
||||
},
|
||||
};
|
||||
|
||||
class SDK {
|
||||
class AwsProvider {
|
||||
static getProviderName() {
|
||||
return 'aws';
|
||||
}
|
||||
|
||||
constructor(serverless) {
|
||||
// Defaults
|
||||
this.sdk = AWS;
|
||||
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)
|
||||
const proxy = process.env.proxy
|
||||
@ -187,4 +192,4 @@ class SDK {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SDK;
|
||||
module.exports = AwsProvider;
|
||||
@ -4,11 +4,11 @@ const sinon = require('sinon');
|
||||
const BbPromise = require('bluebird');
|
||||
const expect = require('chai').expect;
|
||||
const Serverless = require('../../../Serverless');
|
||||
const AwsSdk = require('../');
|
||||
const AwsProvider = require('./awsProvider');
|
||||
const proxyquire = require('proxyquire');
|
||||
|
||||
describe('AWS SDK', () => {
|
||||
let awsSdk;
|
||||
describe('AwsProvider', () => {
|
||||
let awsProvider;
|
||||
let serverless;
|
||||
|
||||
beforeEach(() => {
|
||||
@ -17,24 +17,34 @@ 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('#getProviderName()', () => {
|
||||
it('should return the provider name', () => {
|
||||
expect(AwsProvider.getProviderName()).to.equal('aws');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#constructor()', () => {
|
||||
it('should set AWS instance', () => {
|
||||
expect(typeof awsSdk.sdk).to.not.equal('undefined');
|
||||
it('should set Serverless instance', () => {
|
||||
expect(typeof awsProvider.serverless).to.not.equal('undefined');
|
||||
});
|
||||
|
||||
it('should set Serverless instance', () => {
|
||||
expect(typeof awsSdk.serverless).to.not.equal('undefined');
|
||||
it('should set AWS instance', () => {
|
||||
expect(typeof awsProvider.sdk).to.not.equal('undefined');
|
||||
});
|
||||
|
||||
it('should set the provider property', () => {
|
||||
expect(awsProvider.provider).to.equal(awsProvider);
|
||||
});
|
||||
|
||||
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 +52,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 +75,10 @@ describe('AWS SDK', () => {
|
||||
};
|
||||
}
|
||||
}
|
||||
awsSdk.sdk = {
|
||||
awsProvider.sdk = {
|
||||
S3: FakeS3,
|
||||
};
|
||||
awsSdk.serverless.service.environment = {
|
||||
awsProvider.serverless.service.environment = {
|
||||
vars: {},
|
||||
stages: {
|
||||
dev: {
|
||||
@ -80,7 +90,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 +120,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 +152,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 +178,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 +198,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 +237,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 +247,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 +265,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 +287,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 +308,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 +317,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 +344,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 +358,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 +385,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');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -6,14 +6,11 @@ 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.provider = this.serverless.getProvider('aws');
|
||||
|
||||
Object.assign(this, validate, emptyS3Bucket, removeStack, monitorStack);
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ const BbPromise = require('bluebird');
|
||||
|
||||
module.exports = {
|
||||
setServerlessDeploymentBucketName() {
|
||||
return this.sdk.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.sdk.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.sdk.request('S3', 'deleteObjects', {
|
||||
return this.provider.request('S3', 'deleteObjects', {
|
||||
Bucket: this.bucketName,
|
||||
Delete: {
|
||||
Objects: this.objectsInBucket,
|
||||
|
||||
@ -13,7 +13,7 @@ module.exports = {
|
||||
StackId: stackName,
|
||||
};
|
||||
|
||||
return this.sdk.request('CloudFormation',
|
||||
return this.provider.request('CloudFormation',
|
||||
'deleteStack',
|
||||
params,
|
||||
this.options.stage,
|
||||
|
||||
@ -2,12 +2,14 @@
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const AwsProvider = require('../../provider/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.provider, '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.provider.getServerlessDeploymentBucketName.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#listObjects()', () => {
|
||||
it('should resolve if no objects are present', () => {
|
||||
const listObjectsStub = sinon.stub(awsRemove.sdk, 'request')
|
||||
const listObjectsStub = sinon.stub(awsRemove.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
it('should push objects to the array if present', () => {
|
||||
const listObjectsStub = sinon.stub(awsRemove.sdk, 'request')
|
||||
const listObjectsStub = sinon.stub(awsRemove.provider, '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.provider.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.provider, '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.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
const expect = require('chai').expect;
|
||||
const BbPromise = require('bluebird');
|
||||
const sinon = require('sinon');
|
||||
const AwsRemove = require('../');
|
||||
const AwsProvider = require('../../provider/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);
|
||||
|
||||
@ -2,12 +2,14 @@
|
||||
|
||||
const expect = require('chai').expect;
|
||||
const sinon = require('sinon');
|
||||
const AwsProvider = require('../../provider/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.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.sdk.request.restore();
|
||||
awsRemove.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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('../provider/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.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.sdk, '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.sdk.request.restore();
|
||||
awsPlugin.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
it('should skip monitoring if the stack was already created', () => {
|
||||
const describeStackEventsStub = sinon.stub(awsPlugin.sdk, 'request');
|
||||
const describeStackEventsStub = sinon.stub(awsPlugin.provider, 'request');
|
||||
|
||||
return awsPlugin.monitorStack('update', 'alreadyCreated', 10).then(() => {
|
||||
expect(describeStackEventsStub.callCount).to.be.equal(0);
|
||||
awsPlugin.sdk.request.restore();
|
||||
awsPlugin.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
it('should keep monitoring until CREATE_COMPLETE stack status', () => {
|
||||
const describeStackEventsStub = sinon.stub(awsPlugin.sdk, '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.sdk.request.restore();
|
||||
awsPlugin.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
it('should keep monitoring until UPDATE_COMPLETE stack status', () => {
|
||||
const describeStackEventsStub = sinon.stub(awsPlugin.sdk, '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.sdk.request.restore();
|
||||
awsPlugin.provider.request.restore();
|
||||
});
|
||||
});
|
||||
|
||||
it('should keep monitoring until DELETE_COMPLETE stack status', () => {
|
||||
const describeStackEventsStub = sinon.stub(awsPlugin.sdk, '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.sdk.request.restore();
|
||||
awsPlugin.provider.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.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.sdk.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.sdk, '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.sdk.request.restore();
|
||||
awsPlugin.provider.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.provider, 'request');
|
||||
const cfDataMock = {
|
||||
StackId: 'new-service-dev',
|
||||
};
|
||||
@ -307,12 +307,12 @@ describe('monitorStack', () => {
|
||||
awsPlugin.options.stage,
|
||||
awsPlugin.options.region
|
||||
));
|
||||
awsPlugin.sdk.request.restore();
|
||||
awsPlugin.provider.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.provider, 'request');
|
||||
const cfDataMock = {
|
||||
StackId: 'new-service-dev',
|
||||
};
|
||||
@ -380,7 +380,7 @@ describe('monitorStack', () => {
|
||||
awsPlugin.options.stage,
|
||||
awsPlugin.options.region
|
||||
));
|
||||
awsPlugin.sdk.request.restore();
|
||||
awsPlugin.provider.request.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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"
|
||||
|
||||
18
tests/all.js
18
tests/all.js
@ -1,14 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
// Serverless Core Tests
|
||||
require('./classes/Serverless');
|
||||
require('./classes/PluginManager');
|
||||
require('./classes/Utils');
|
||||
require('./classes/Config');
|
||||
require('./classes/Service');
|
||||
require('./classes/Variables');
|
||||
require('./classes/YamlParser');
|
||||
require('./classes/CLI');
|
||||
require('../lib/Serverless.test');
|
||||
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');
|
||||
@ -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/aws/provider/awsProvider.test');
|
||||
require('../lib/plugins/aws/tests/validate');
|
||||
require('../lib/plugins/aws/tests/monitorStack');
|
||||
require('../lib/plugins/aws/info/tests');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user