mirror of
https://github.com/serverless/serverless.git
synced 2026-01-25 15:07:39 +00:00
deploy resources: complete command
This commit is contained in:
parent
54f4e5a6b6
commit
a2dce9c8be
@ -288,7 +288,7 @@ Deployer.prototype.deploy = Promise.method(function() {
|
||||
})
|
||||
.then(function() {
|
||||
spinner.stop(true);
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(function() {
|
||||
|
||||
@ -2,10 +2,9 @@
|
||||
|
||||
/**
|
||||
* JAWS Command: deploy resources <stage> <region>
|
||||
* - Deploys project's API Gateway REST API to the specified stage and one or all regions
|
||||
* - Deploys project's resources-cf.json
|
||||
*/
|
||||
|
||||
|
||||
var JawsError = require('../jaws-error'),
|
||||
JawsCli = require('../utils/cli'),
|
||||
Promise = require('bluebird'),
|
||||
@ -27,8 +26,8 @@ Promise.promisifyAll(fs);
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
module.exports.run = function(JAWS, stage, region, allTagged) {
|
||||
var command = new CMD(JAWS, stage, region, allTagged);
|
||||
module.exports.run = function(JAWS, stage, region) {
|
||||
var command = new CMD(JAWS, stage, region);
|
||||
return command.run();
|
||||
};
|
||||
|
||||
@ -37,18 +36,13 @@ module.exports.run = function(JAWS, stage, region, allTagged) {
|
||||
* @param JAWS
|
||||
* @param stage
|
||||
* @param region
|
||||
* @param allTagged
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function CMD(JAWS, stage, region, allTagged) {
|
||||
function CMD(JAWS, stage, region) {
|
||||
var _this = this;
|
||||
_this._stage = stage;
|
||||
_this._allTagged = allTagged;
|
||||
_this._JAWS = JAWS;
|
||||
_this._prjJson = JAWS._meta.projectJson;
|
||||
_this._prjRootPath = JAWS._meta.projectRootPath;
|
||||
_this._prjCreds = JAWS._meta.credentials;
|
||||
|
||||
if (region && stage) {
|
||||
_this._regions = _this._JAWS._meta.projectJson.stages[_this._stage].filter(function(r) {
|
||||
@ -70,43 +64,34 @@ CMD.prototype.run = Promise.method(function() {
|
||||
// Flow
|
||||
return _this._JAWS.validateProject()
|
||||
.bind(_this)
|
||||
.then(function() {
|
||||
// If !allTagged, tag current directory
|
||||
if (!_this._allTagged) {
|
||||
return CMDtag.tag('endpoint', null, false);
|
||||
.then(_this._promptStage)
|
||||
.then(function(answer) {
|
||||
if (answer) _this._stage = answer[0].value;
|
||||
})
|
||||
.then(_this._promptRegions)
|
||||
.then(function(answer) {
|
||||
if (answer) {
|
||||
_this._regions = [utils.getProjRegionConfigForStage(_this._JAWS, _this._stage, answer[0].value)];
|
||||
}
|
||||
})
|
||||
.then(_this._promptStage)
|
||||
.then(_this._promptRegions)
|
||||
.then(function() {
|
||||
return _this._regions;
|
||||
})
|
||||
.each(function(regionJson) {
|
||||
|
||||
JawsCli.log('Endpoint Deployer: Deploying endpoint(s) to region "' + regionJson.region + '"...');
|
||||
JawsCli.log('Resources Deployer "'
|
||||
+ _this._stage
|
||||
+ '": Deploying resources to region "'
|
||||
+ regionJson.region
|
||||
+ '"...');
|
||||
|
||||
var deployer = new ApiDeployer(
|
||||
var deployer = new ResourceDeployer(
|
||||
_this._JAWS,
|
||||
_this._stage,
|
||||
regionJson,
|
||||
_this._prjRootPath,
|
||||
_this._prjJson,
|
||||
_this._prjCreds
|
||||
regionJson
|
||||
);
|
||||
|
||||
return deployer.deploy()
|
||||
.then(function(url) {
|
||||
JawsCli.log('Endpoint Deployer: Endpoints for stage "'
|
||||
+ _this._stage
|
||||
+ '" successfully deployed to API Gateway in the region "'
|
||||
+ regionJson.region
|
||||
+ '". Access them @ '
|
||||
+ url);
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
// Untag All tagged endpoints
|
||||
return _this._allTagged ? CMDtag.tagAll(_this._JAWS, 'endpoint', true) : CMDtag.tag('endpoint', null, true);
|
||||
return deployer.deploy();
|
||||
});
|
||||
});
|
||||
|
||||
@ -121,7 +106,7 @@ CMD.prototype._promptStage = Promise.method(function() {
|
||||
// If stage, skip
|
||||
if (_this._stage) return;
|
||||
|
||||
var stages = Object.keys(_this._prjJson.stages);
|
||||
var stages = Object.keys(_this._JAWS._meta.projectJson.stages);
|
||||
if (!stages.length) {
|
||||
throw new JawsError('You have no stages in this project');
|
||||
}
|
||||
@ -175,3 +160,76 @@ CMD.prototype._promptRegions = Promise.method(function() {
|
||||
return JawsCli.select('Select a region in this stage to deploy to: ', choices, false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Resource Deployer
|
||||
* @param JAWS
|
||||
* @param stage
|
||||
* @param region
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function ResourceDeployer(JAWS, stage, region) {
|
||||
|
||||
var _this = this;
|
||||
_this._JAWS = JAWS;
|
||||
_this._stage = stage;
|
||||
_this._regionJson = region;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource Deployer: Deploy
|
||||
*/
|
||||
|
||||
ResourceDeployer.prototype.deploy = Promise.method(function() {
|
||||
|
||||
var _this = this;
|
||||
|
||||
JawsCli.log('Resources Deployer "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": Performing Cloudformation stack update. '
|
||||
+ 'This could take a while depending on how many resources you are updating...');
|
||||
|
||||
var spinner = JawsCli.spinner();
|
||||
spinner.start();
|
||||
|
||||
return _this._updateStack()
|
||||
.bind(_this)
|
||||
.then(function(cfData) {
|
||||
return AWSUtils.monitorCf(cfData, _this._JAWS._meta.profile, _this._regionJson.region, 'update');
|
||||
})
|
||||
.then(function(data) {
|
||||
spinner.stop(true);
|
||||
JawsCli.log('Resources Deployer "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": Cloudformation stack update completed successfully!');
|
||||
})
|
||||
.catch(function(error) {
|
||||
spinner.stop(true);
|
||||
JawsCli.log('Resources Deployer "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": Cloudformation stack update failed because of the following error...');
|
||||
console.log(error);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Resource Deployer: Update Stack
|
||||
*/
|
||||
|
||||
ResourceDeployer.prototype._updateStack = Promise.method(function() {
|
||||
|
||||
var _this = this;
|
||||
|
||||
// Fetch Cloudformation template
|
||||
return AWSUtils.cfUpdateResourcesStack(
|
||||
_this._JAWS,
|
||||
_this._stage,
|
||||
_this._regionJson.region);
|
||||
});
|
||||
|
||||
@ -144,6 +144,19 @@ CMD.prototype._prompt = Promise.method(function() {
|
||||
},
|
||||
};
|
||||
|
||||
// Prompt: notification email - for AWS alerts
|
||||
_this.Prompter.override.notificationEmail = _this._notificationEmail;
|
||||
_this._prompts.properties.notificationEmail = {
|
||||
description: 'Enter an email to use for AWS alarms: '.yellow,
|
||||
required: true,
|
||||
message: 'Please enter a valid email',
|
||||
default: 'you@yourapp.com',
|
||||
conform: function(email) {
|
||||
if (!email) return false;
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
// Prompt: s3 bucket - holds env vars for this project
|
||||
_this.Prompter.override.s3Bucket = _this._s3Bucket;
|
||||
_this._prompts.properties.s3Bucket = {
|
||||
|
||||
@ -215,7 +215,7 @@ CMD.prototype._validate = Promise.method(function() {
|
||||
|
||||
// Make sure region is not already defined
|
||||
if (_this._JAWS._meta.projectJson.stages[_this._stage].some(function(r) {
|
||||
return r.region == _this._region
|
||||
return r.region == _this._region;
|
||||
})) {
|
||||
throw new JawsError('Region "' + _this._region + '" is already defined in the stage "' + _this._stage + '"');
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ exports.validLambdaRegions = [
|
||||
'us-east-1',
|
||||
'us-west-2', //oregon
|
||||
'eu-west-1', //Ireland
|
||||
'ap-northeast-1' //Tokyo
|
||||
'ap-northeast-1', //Tokyo
|
||||
];
|
||||
|
||||
/**
|
||||
@ -456,7 +456,7 @@ exports.cfUpdateLambdasStack = function(JAWS, stage, region, lambdaRoleArn) {
|
||||
};
|
||||
|
||||
/**
|
||||
* CloudFormation: Create Stack
|
||||
* CloudFormation: Create Resources Stack
|
||||
* @param awsProfile
|
||||
* @param awsRegion
|
||||
* @param projRootPath
|
||||
@ -520,6 +520,45 @@ exports.cfCreateResourcesStack = function(awsProfile, awsRegion, projRootPath, p
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* CloudFormation: Update Resources Stack
|
||||
* @param JAWS
|
||||
* @param stage
|
||||
* @param region
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
exports.cfUpdateResourcesStack = function(JAWS, stage, region) {
|
||||
|
||||
var _this = this,
|
||||
awsProfile = JAWS._meta.profile,
|
||||
projRootPath = JAWS._meta.projectRootPath,
|
||||
bucketName = JAWS._meta.projectJson.jawsBuckets[region],
|
||||
projName = JAWS._meta.projectJson.name;
|
||||
|
||||
_this.configAWS(awsProfile, region);
|
||||
|
||||
var CF = Promise.promisifyAll(new AWS.CloudFormation({
|
||||
apiVersion: '2010-05-15',
|
||||
})),
|
||||
stackName = _this.cfGetResourcesStackName(stage, projName);
|
||||
|
||||
var params = {
|
||||
StackName: stackName,
|
||||
Capabilities: [
|
||||
'CAPABILITY_IAM',
|
||||
],
|
||||
UsePreviousTemplate: false,
|
||||
Parameters: []
|
||||
};
|
||||
|
||||
return _this.putCfFile(awsProfile, projRootPath, region, bucketName, projName, stage, 'resources')
|
||||
.then(function(templateUrl) {
|
||||
params.TemplateURL = templateUrl;
|
||||
return CF.updateStackAsync(params);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* CloudFormation: Monitor CF Stack Status (Create/Update)
|
||||
* @param cfData
|
||||
@ -878,7 +917,7 @@ exports.lambdaRemovePermission = function(awsProfile, awsRegion, functionName, s
|
||||
|
||||
var params = {
|
||||
FunctionName: functionName, /* required */
|
||||
StatementId: statementId /* required */
|
||||
StatementId: statementId, /* required */
|
||||
};
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
@ -26,6 +26,7 @@ describe('AllTests', function() {
|
||||
*/
|
||||
//require('./cli/dash');
|
||||
//require('./cli/deploy_lambda');
|
||||
//require('./cli/deploy_resources');
|
||||
//require('./cli/deploy_endpoint');
|
||||
//require('./cli/new_stage_region');
|
||||
//require('./cli/new_project');
|
||||
|
||||
57
tests/cli/deploy_resources.js
Normal file
57
tests/cli/deploy_resources.js
Normal file
@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* JAWS Test: Deploy Resources
|
||||
*/
|
||||
|
||||
var Jaws = require('../../lib/index.js'),
|
||||
CmdDeployResources = require('../../lib/commands/deploy_resources'),
|
||||
CmdTag = require('../../lib/commands/tag'),
|
||||
JawsError = require('../../lib/jaws-error'),
|
||||
testUtils = require('../test_utils'),
|
||||
Promise = require('bluebird'),
|
||||
path = require('path'),
|
||||
assert = require('chai').assert,
|
||||
config = require('../config'),
|
||||
lambdaPaths = {},
|
||||
projPath,
|
||||
JAWS;
|
||||
|
||||
describe('Test deploy resources command', function() {
|
||||
|
||||
before(function(done) {
|
||||
testUtils.createTestProject(
|
||||
config.name,
|
||||
config.region,
|
||||
config.stage,
|
||||
config.iamRoleArnLambda,
|
||||
config.iamRoleArnApiGateway,
|
||||
config.usEast1Bucket)
|
||||
.then(function(pp) {
|
||||
projPath = pp;
|
||||
process.chdir(path.join(projPath));
|
||||
JAWS = new Jaws();
|
||||
})
|
||||
.then(done);
|
||||
});
|
||||
|
||||
describe('Positive tests', function() {
|
||||
|
||||
it('Deploy Resources', function(done) {
|
||||
|
||||
this.timeout(0);
|
||||
|
||||
CmdDeployResources.run(JAWS, config.stage, config.region)
|
||||
.then(function() {
|
||||
done();
|
||||
})
|
||||
.catch(JawsError, function(e) {
|
||||
done(e);
|
||||
})
|
||||
.error(function(e) {
|
||||
console.log(e);
|
||||
done(e);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user