Merge pull request #142 from jaws-framework/v1-stage-region

fixing new stage/region command
This commit is contained in:
Austen 2015-09-21 20:22:12 -07:00
commit cc937285b0
8 changed files with 263 additions and 168 deletions

View File

@ -7,7 +7,6 @@ var JawsError = require('../lib/jaws-error'),
program = require('commander'),
utils = require('../lib/utils'),
Promise = require('bluebird'),
minimist = require('minimist'),
execute = utils.execute;
Promise.onPossiblyUnhandledRejection(function(error) {
@ -22,50 +21,69 @@ program
/**
* New
* - Create a new project|stage|region|action
* - Create a new project|stage|region
*/
program
.command('new <type>')
.allowUnknownOption()
.description('Make a new "project", "stage", "region", or "module <module_name> <action>"')
.action(function() {
.command('new <cmd> [params]')
.description('new project, stage and region commands\n\nValid <cmd>\'s:' +
'\n\nproject: create new JAWS project in CWD.' +
'\n\t Ex: jaws new project' +
'\n\nstage: create new stage in existing region' +
'\n\t Ex: jaws new stage dev' +
'\n\nregion: create new region for given stage' +
'\n\t Ex: jaws new region dev'
)
.option('-d, --dont-exe-cf', 'Don\'t execute CloudFormation, just generate it.')
.option('-r, --region <name>', 'name of aws region to use')
.option('-b, --s3-bucket <name>', 'project & region only: JAWS S3 bucket name. Will be created if DNE in "project" cmd. Must exist for "region" cmd.')
.option('-n, --proj-name <name>', 'project only: name for new project')
.option('-s, --stage <name>', 'project only: same of stage for new project')
.option('-e, --email <email>', 'project only: notification email to use in CloudFormation')
.option('-p, --aws-profile <profileName>', 'project only: Admin AWS profile as defined in ~/.aws/credentials to use')
.action(function(cmd, params, options) {
// Parse Args
var args = minimist(process.argv.slice(3));
var type = args._[0] ? args._[0].toLowerCase() : null;
if (type == 'project') {
// New Project
if (cmd == 'project') {
var CmdNewProject = require('../lib/commands/new_project');
execute(CmdNewProject.run(
args.name,
args.stage ? args.stage.toLowerCase() : null,
args.s3Bucket,
args.region,
args.email,
args.profile,
args.noExeCf
options.projName,
options.stage ? options.stage.toLowerCase() : null,
options.s3Bucket,
options.region,
options.email,
options.awsProfile,
options.dontExeCf
));
} else if (type == 'region' || type == 'stage') {
} else if (cmd == 'region' || cmd == 'stage') {
var theParams = process.argv.slice(3);
if (!theParams) {
throw new JawsError('Missing params', JawsError.errorCodes.UNKNOWN);
}
if (theParams[0][0] == '-') { //TODO: how do we get around this commander shortcoming?
throw new JawsError('Specify options after cmd', JawsError.errorCodes.UNKNOWN);
}
//TODO: iterate thru cmds to see how many are before -
if (theParams.length < 2) {
throw new JawsError('must specify stage name', JawsError.errorCodes.UNKNOWN);
}
var CmdNewStageRegion = require('../lib/commands/new_stage_region'),
stageName = theParams[1];
// New Region/Stage
var CmdNewStageRegion = require('../lib/commands/new_stage_region');
execute(CmdNewStageRegion.run(
JAWS,
type,
args.stage,
args.region,
args.noExeCf
cmd,
stageName,
options.region,
options.s3Bucket,
options.dontExeCf
));
} else {
// Unknown Type
console.error('Unsupported type ' + type + '. Must be project|region|stage|module');
console.error('Unsupported cmd ' + cmd + '. Must be project|stage|region');
process.exit(1);
}
});
@ -77,10 +95,10 @@ program
program
.command('module <cmd> [params]')
.description('aws-module commands\n\nValid <cmd>' +
'\'s:\n\ninstall: install aws-module.' +
.description('aws-module commands\n\nValid <cmd>\'s:' +
'\n\ninstall: install aws-module.' +
'\n\t Ex: jaws module install <url>' +
'\n\tupdate: update aws-module' +
'\n\nupdate: update aws-module' +
'\n\t Ex: jaws module update <url>' +
'\n\ncreate: create aws-module action. Module will be created if DNE. create <module resource> <action>' +
'\n\t Ex: jaws module create users list'
@ -89,15 +107,19 @@ program
.option('-d, --dont-install-dependencies', 'Install&Update Only: DONT install awsm\'s depdencies automatically')
.option('-l, --lambda', 'Create Only: create lambda. Default is create lambda and endpoint.')
.option('-e, --endpoint', 'Create Only: create API Gateway endpoint. Default is create lambda and endpoint.')
.option('-r, --runtime', 'Create Only: lambda runtime. Default nodejs')
.option('-r, --runtime <name>', 'Create Only: lambda runtime. Default nodejs')
.action(function(cmd, params, options) {
var theParams = process.argv.slice(3);
if (!theParams) {
throw new JawsError('Missing params', JawsError.errorCodes.UNKNOWN);
}
if (theParams[0][0] == '-') { //TODO: how do we get around this commander shortcoming?
throw new JawsError('Specify options after cmd', JawsError.errorCodes.UNKNOWN);
}
if (cmd == 'install' || cmd == 'update') {
if (theParams.length !== 2) {
//TODO: iterate thru cmds to see how many are before -
if (theParams.length < 2) {
throw new JawsError('Please specify awsm url', JawsError.errorCodes.UNKNOWN);
}
var url = theParams[1],
@ -105,7 +127,7 @@ program
execute(theCmd[cmd](JAWS, url, options.save, options.dontInstallDependencies));
} else if (cmd == 'create') {
if (theParams.length !== 3) {
if (theParams.length < 3) {
throw new JawsError('Please specify awsm resource and action name');
}

View File

@ -71,6 +71,7 @@ function CMD(name, stage, s3Bucket, notificationEmail, region, profile, noCf) {
};
this.Prompter = JawsCLI.prompt();
this.Prompter.override = {};
this._spinner = null;
}
/**
@ -123,7 +124,7 @@ CMD.prototype._prompt = Promise.method(function() {
_this.Prompter.override.name = _this._name;
_this._prompts.properties.name = {
description: 'Enter a project name: '.yellow,
default: 'jaws-' + shortid.generate().replace(/\W+/g, '').substring(0, 19).replace('_',''),
default: 'jaws-' + shortid.generate().replace(/\W+/g, '').substring(0, 19).replace('_', ''),
message: 'Name must be only letters, numbers, underscores or dashes',
conform: function(name) {
var re = /^[a-zA-Z0-9-_]+$/;
@ -194,17 +195,8 @@ CMD.prototype._prompt = Promise.method(function() {
}
// Show Prompts
return new Promise(function(resolve, reject) {
_this.Prompter.get(_this._prompts, function(err, answers) {
if (err) {
reject(new JawsError(err));
}
resolve(answers);
});
})
return _this.Prompter.getAsync(_this._prompts)
.then(function(answers) {
// Set Answers
_this._name = answers.name;
_this._stage = answers.stage.toLowerCase();
_this._s3Bucket = answers.s3Bucket;
@ -213,20 +205,21 @@ CMD.prototype._prompt = Promise.method(function() {
_this._awsAdminSecretKey = answers.awsAdminSecretKey;
// If region exists, skip select prompt
if (_this._region) return Promise.resolve();
if (_this._region) return;
// Prompt: region select
var choices = [
{key: '', label: 'us-east-1', value: 'us-east-1'},
{key: '', label: 'us-west-2', value: 'us-west-2'},
{key: '', label: 'eu-west-1', value: 'eu-west-1'},
{key: '', label: 'ap-northeast-1', value: 'ap-northeast-1'},
];
var choices = [];
AWSUtils.validLambdaRegions.forEach(function(r) {
choices.push({
key: '',
value: r,
label: r,
});
});
return JawsCLI.select('Select a region for your project: ', choices, false)
.then(function(results) {
_this._region = results[0].value;
return Promise.resolve();
});
})
.then(function() {
@ -250,7 +243,6 @@ CMD.prototype._prompt = Promise.method(function() {
return JawsCLI.select('Select a profile for your project: ', choices, false)
.then(function(results) {
_this._profile = results[0].value;
return Promise.resolve();
});
});
});
@ -331,7 +323,6 @@ CMD.prototype._createProjectDirectory = Promise.method(function() {
path.join(_this._projectRootPath, 'back', '.env'),
'JAWS_STAGE=' + _this._stage
+ '\nJAWS_DATA_MODEL_PREFIX=' + _this._stage
+ '\nJAWS_REGION=' + _this._region
)
.then(function() {
return Promise.all([
@ -339,10 +330,7 @@ CMD.prototype._createProjectDirectory = Promise.method(function() {
fs.mkdirAsync(path.join(_this._projectRootPath, 'tests')),
fs.mkdirAsync(path.join(_this._projectRootPath, 'back', 'aws_modules')),
utils.writeFile(path.join(_this._projectRootPath, 'admin.env'), adminEnv),
utils.writeFile(path.join(
_this._projectRootPath, 'cloudformation', _this._stage, _this._region, 'resources-cf.json'),
JSON.stringify(cfTemplate, null, 2)
),
utils.generateResourcesCf(_this._projectRootPath, _this._name, _this._stage, _this._region, _this._notificationEmail),
]);
});
});
@ -364,8 +352,7 @@ CMD.prototype._createS3JawsStructure = Promise.method(function() {
.then(function() {
var envFileContents = 'JAWS_STAGE=' + _this._stage
+ '\nJAWS_DATA_MODEL_PREFIX=' + _this._stage
+ '\nJAWS_REGION=' + _this._region;
+ '\nJAWS_DATA_MODEL_PREFIX=' + _this._stage;
return AWSUtils.putEnvFile(
_this._profile,
@ -385,9 +372,7 @@ CMD.prototype._createCfStack = Promise.method(function() {
var _this = this;
// Start loading icon
JawsCLI.log('Creating CloudFormation Stack for your new project (~5 mins)...');
_this._spinner = JawsCLI.spinner('');
_this._spinner = JawsCLI.spinner('Creating CloudFormation Stack for your new project (~5 mins)...');
_this._spinner.start();
// Create CF stack

View File

@ -7,7 +7,7 @@
*/
var JawsError = require('../jaws-error'),
JawsCli = require('../utils/cli'),
JawsCLI = require('../utils/cli'),
Promise = require('bluebird'),
fs = require('fs'),
path = require('path'),
@ -17,11 +17,17 @@ var JawsError = require('../jaws-error'),
Promise.promisifyAll(fs);
/**
* Run
*
* @param JAWS
* @param type 'stage'|'region'
* @param stage
* @param region Optional. Will be prompted for if omitted
* @param s3Bucket Optional. only valid for type of region
* @param noCf Optional
* @returns {*}
*/
module.exports.run = function(JAWS, type, stage, region, noCf) {
var command = new CMD(JAWS, type, stage, region, noCf);
module.exports.run = function(JAWS, type, stage, region, s3Bucket, noCf) {
var command = new CMD(JAWS, type, stage, region, s3Bucket, noCf);
return command.run();
};
@ -29,13 +35,14 @@ module.exports.run = function(JAWS, type, stage, region, noCf) {
* Command Class
* @constructor
*/
function CMD(JAWS, type, stage, region, noCf) {
function CMD(JAWS, type, stage, region, s3Bucket, noCf) {
this._JAWS = JAWS;
this._type = type;
this._stage = stage;
this._region = region;
this._s3Bucket = s3Bucket;
this._noCf = noCf;
this._spinner = null;
}
/**
@ -47,15 +54,49 @@ CMD.prototype.run = Promise.method(function() {
var _this = this;
// Status
if (_this._type === 'stage') JawsCli.log('Creating new stage "' + _this._stage + '"...');
if (_this._type === 'region') JawsCli.log('Creating new region within stage "' + _this._stage + '"...');
if (_this._type === 'stage') JawsCLI.log('Creating new stage "' + _this._stage + '"...');
if (_this._type === 'region') JawsCLI.log('Creating new region within stage "' + _this._stage + '"...');
return _this._JAWS.validateProject()
.bind(_this)
.then(_this._promptRegion)
.then(function() {
if (_this._type == 'stage') { //if stage we now have region, so we know bucket
_this._s3Bucket = _this._JAWS._meta.projectJson.jawsBuckets[_this._region];
} else {
return _this._promptJawsS3Bucket();
}
})
.then(_this._validate)
.then(_this._createEnvFile)
.then(_this._createCfStack)
.then(function() {
return utils.generateResourcesCf(
_this._JAWS._meta.projectRootPath,
_this._JAWS._meta.projectJson.name,
_this._stage,
_this._region,
''
);
})
.then(function() {
if (_this._noCf) {
JawsCLI.log('ENV var file created in s3. CloudFormation file can be run manually');
JawsCLI.log('!!MAKE SURE!! to create stack with name: ' + AWSUtils.cfGetResourcesStackName(
_this._stage,
_this._JAWS._meta.projectJson.name
));
JawsCLI.log('After creating CF stack, remember to put the IAM role outputs in your project jaws.json');
return false;
} else {
return _this._createCfStack()
.then(function(cfData) {
if (_this._spinner) {
_this._spinner.stop(true);
}
return cfData;
});
}
})
.then(_this._updateProjectJson);
});
@ -64,36 +105,70 @@ CMD.prototype.run = Promise.method(function() {
*/
CMD.prototype._promptRegion = Promise.method(function() {
var _this = this,
msg = 'Choose a region lambda supports: ',
validRegions = AWSUtils.validLambdaRegions;
var _this = this;
// If region exists, skip
if (_this._region) return;
var regions = [
'us-east-1',
'us-west-1',
'us-west-2',
'eu-west-1',
'ap-northeast-1',
];
// Create Choices
var choices = [];
for (var i = 0; i < (regions.length + 1); i++) {
choices.push({
key: (i + 1) + ') ',
value: regions[i],
label: regions[i],
});
if (_this._type == 'stage') { //must use existing region
validRegions = Object.keys(_this._JAWS._meta.projectJson.jawsBuckets);
if (validRegions.length == 1) {
_this._region = validRegions[0];
return Promise.resolve();
}
msg = 'Choose an existing project region: ';
}
return JawsCli.select('Choose a region within this stage: ', choices, false)
if (validRegions.indexOf(_this._region) != -1) { //they specified region and its valid
return Promise.resolve();
}
var choices = [];
validRegions.forEach(function(r) {
choices.push({
key: '',
value: r,
label: r,
});
});
return JawsCLI.select(msg, choices, false)
.then(function(results) {
_this._region = [results[0].value];
console.log('results', results[0].value);
_this._region = results[0].value;
});
});
CMD.prototype._promptJawsS3Bucket = function() {
var _this = this;
//Don't ever auto-create s3 bucket as its against best practice, and this is not the quick start path
var Prompter = JawsCLI.prompt(),
prompts = {
properties: {
s3Bucket: {
description: 'Enter EXISTING s3 bucket for this region. Must be in THIS region: '.yellow,
required: true,
default: 'jaws-' + _this._region + '.yourapp.com',
message: 'Bucket name must only contain lowercase letters, numbers, periods and dashes',
conform: function(bucket) {
var re = /^[a-z0-9-.]+$/;
return re.test(bucket);
}
}
}
};
Prompter.override = {
s3Bucket: _this._s3Bucket,
};
return Prompter.getAsync(prompts)
.then(function(answers) {
_this._s3Bucket = answers.s3Bucket;
return _this._s3Bucket;
});
};
/**
* CMD: Validate
*/
@ -103,7 +178,7 @@ CMD.prototype._validate = Promise.method(function() {
var _this = this;
// Check project config is valid
if (!_this._JAWS._meta.projectJson.project || !_this._JAWS._meta.projectJson.stages) {
if (!_this._JAWS._meta.projectJson.stages) {
throw new JawsError('Project\'s jaws.json is malformed or has no existing stages object defined');
}
@ -122,7 +197,7 @@ CMD.prototype._validate = Promise.method(function() {
// Make sure stage is not already defined in s3 env var - don't want to overwrite it
var envCmd = require('./env');
return envCmd.getEnvFileAsMap(_this._JAWS, _this._stage)
return envCmd.getEnvFileAsMap(_this._JAWS, _this._stage, _this._region)
.then(function(envMap) {
if (Object.keys(envMap).length > 0) {
throw new JawsError('Stage "' + _this._stage + '" can not be created as an env var file already exists');
@ -151,17 +226,13 @@ CMD.prototype._createEnvFile = Promise.method(function() {
var _this = this;
// If type is not stage, skip this
if (_this._type !== 'stage') return;
var envFileContents = 'JAWS_STAGE=' + _this._stage
+ '\nJAWS_DATA_MODEL_PREFIX=' + _this._stage
+ '\nJAWS_REGION=' + _this._region;
+ '\nJAWS_DATA_MODEL_PREFIX=' + _this._stage;
return AWSUtils.putEnvFile(
_this._JAWS._meta.profile,
_this._JAWS._meta.projectJson.envVarBucket.region,
_this._JAWS._meta.projectJson.envVarBucket.name,
_this._region,
_this._s3Bucket,
_this._JAWS._meta.projectJson.name,
_this._stage,
envFileContents);
@ -175,31 +246,25 @@ CMD.prototype._createCfStack = Promise.method(function() {
var _this = this;
// Start loading icon
var spinner = JawsCli.spinner(
'Creating CloudFormation stack "'
_this._spinner = JawsCLI.spinner(
'Creating CloudFormation stack for stage: "'
+ _this._stage
+ '" - "'
+ '" and region: "'
+ _this._region
+ '"');
spinner.start();
+ '" (~5 mins)');
_this._spinner.start();
return AWSUtils.cfCreateResourcesStack(
_this._JAWS._meta.profile,
_this._region,
_this._JAWS._meta.projectRootPath,
_this._JAWS._meta.projectJson.name,
_this._stage,
_this._JAWS._meta.projectJson.jawsBuckets[_this._region],
'' // TODO: read email out of existing jaws-cf.json?
)
_this._JAWS._meta.profile,
_this._region,
_this._JAWS._meta.projectRootPath,
_this._JAWS._meta.projectJson.name,
_this._stage,
_this._JAWS._meta.projectJson.jawsBuckets[_this._region],
'' // TODO: read email out of existing jaws-cf.json?
)
.then(function(cfData) {
return AWSUtils.monitorCf(cfData, _this._JAWS._meta.profile, _this._region, 'create')
.then(function(cfData) {
_this._cfData = cfData;
spinner.stop(true);
JawsCli.log('CloudFormation Stack "' + cfData.StackName + '" successfully created.');
});
return AWSUtils.monitorCf(cfData, _this._JAWS._meta.profile, _this._region, 'create');
});
});
@ -207,21 +272,25 @@ CMD.prototype._createCfStack = Promise.method(function() {
* CMD: Update Project JSON
*/
CMD.prototype._updateProjectJson = Promise.method(function() {
CMD.prototype._updateProjectJson = Promise.method(function(cfData) {
var _this = this;
var regionObj = {
region: _this._region,
iamRoleArnLambda: '',
iamRoleArnApiGateway: '',
};
for (var i = 0; i < _this._cfData.Outputs.length; i++) {
if (_this._cfData.Outputs[i].OutputKey === 'IamRoleArnLambda') {
regionObj.IamRoleArnLambda = _this._cfData.Outputs[i].OutputValue;
}
if (cfData) {
for (var i = 0; i < cfData.Outputs.length; i++) {
if (cfData.Outputs[i].OutputKey === 'IamRoleArnLambda') {
regionObj.IamRoleArnLambda = cfData.Outputs[i].OutputValue;
}
if (_this._cfData.Outputs[i].OutputKey === 'IamRoleArnApiGateway') {
regionObj.iamRoleArnApiGateway = _this._cfData.Outputs[i].OutputValue;
if (cfData.Outputs[i].OutputKey === 'IamRoleArnApiGateway') {
regionObj.iamRoleArnApiGateway = cfData.Outputs[i].OutputValue;
}
}
}

View File

@ -15,6 +15,8 @@ var Promise = require('bluebird'),
Promise.promisifyAll(fs);
exports.validLambdaRegions = ['us-east-1', 'us-west-2', 'eu-west-1', 'ap-northeast-1'];
/**
* Set AWS SDK Creds and region from a given profile
*

View File

@ -16,11 +16,12 @@ var Promise = require('bluebird'),
keypress = require('keypress');
Promise.promisifyAll(fs);
Promise.promisifyAll(prompt);
/**
* ASCII
*/
module.exports.ascii = function() {
exports.ascii = function() {
var art = '';
art = art + ' ____ _____ __ __ _________ ' + os.EOL;
@ -37,7 +38,7 @@ module.exports.ascii = function() {
/**
* Spinner
*/
module.exports.spinner = function(message) {
exports.spinner = function(message) {
var spinner = new Spinner('JAWS: ' + chalk.yellow('%s ' + message));
spinner.setSpinnerString('|/-\\');
return spinner;
@ -46,14 +47,14 @@ module.exports.spinner = function(message) {
/**
* Log
*/
module.exports.log = function(message) {
exports.log = function(message) {
console.log('JAWS: ' + chalk.yellow(message + ' '));
};
/**
* Prompt
*/
module.exports.prompt = function() {
exports.prompt = function() {
prompt.start();
prompt.delimiter = '';
prompt.message = 'JAWS: ';
@ -136,7 +137,7 @@ Select._clear = function() {
// Private: Close
Select._close = function(cb) {
utils.logIfVerbose('Closing select listener');
var _this = this;
process.stdin.pause();
@ -159,15 +160,14 @@ Select._close = function(cb) {
* @param doneLabel
* @returns {Promise}
*/
module.exports.select = function(message, choices, multi, doneLabel) {
exports.select = function(message, choices, multi, doneLabel) {
// Set keypress listener, if not set
if (!Select.state) {
keypress(process.stdin);
process.stdin.on('keypress', function(ch, key) {
var keypressHandler = function(ch, key) {
if (key && key.ctrl && key.name == 'c') {
process.stdin.pause();
@ -208,6 +208,7 @@ module.exports.select = function(message, choices, multi, doneLabel) {
// Check if "done" option
if (Select.state.choices[Select.state.index - 1].action
&& Select.state.choices[Select.state.index - 1].action.toLowerCase() === 'done') {
process.stdin.removeListener('keypress', keypressHandler);
return Select._close();
} else {
@ -215,14 +216,16 @@ module.exports.select = function(message, choices, multi, doneLabel) {
Select.state.choices[Select.state.index - 1].toggled = Select.state.choices[Select.state.index - 1].toggled ? false : true;
if (!Select.state.multi) {
process.stdin.removeListener('keypress', keypressHandler);
Select._close();
} else {
return Select._render();
}
}
}
});
};
process.stdin.on('keypress', keypressHandler);
process.stdin.setRawMode(true);
}

View File

@ -20,7 +20,7 @@ Promise.promisifyAll(fs);
* @param projectRootPath
* @param type lambda|endpoint
*/
module.exports.findAllAwsmPathsOfType = function(projectRootPath, type) {
exports.findAllAwsmPathsOfType = function(projectRootPath, type) {
var _this = this,
jawsJsonAttr;
switch (type) {
@ -64,7 +64,7 @@ module.exports.findAllAwsmPathsOfType = function(projectRootPath, type) {
* @param startDir
* @returns {*}
*/
module.exports.findProjectRootPath = function(startDir) {
exports.findProjectRootPath = function(startDir) {
var _this = this;
// Check if startDir is root
@ -99,7 +99,7 @@ module.exports.findProjectRootPath = function(startDir) {
* @param promise
*/
module.exports.execute = function(promise) {
exports.execute = function(promise) {
promise
.catch(JawsError, function(e) {
console.error(e);
@ -118,7 +118,7 @@ module.exports.execute = function(promise) {
* @param filter
* @returns {Promise}
*/
module.exports.readRecursively = function(path, filter) {
exports.readRecursively = function(path, filter) {
return new Promise(function(resolve, reject) {
var files = [];
@ -145,7 +145,7 @@ module.exports.readRecursively = function(path, filter) {
* @param projectRootPath
* @returns {Promise} list of full paths to awsm.json files that are type lambda
*/
module.exports.findAllLambdas = function(projectRootPath) {
exports.findAllLambdas = function(projectRootPath) {
return this.findAllAwsmPathsOfType(projectRootPath, 'lambda');
};
@ -155,7 +155,7 @@ module.exports.findAllLambdas = function(projectRootPath) {
* @param projectRootPath
* @returns {Promise} list of full paths to awsm.json files that are type endpoint
*/
module.exports.findAllEndpoints = function(projectRootPath) {
exports.findAllEndpoints = function(projectRootPath) {
return this.findAllAwsmPathsOfType(projectRootPath, 'endpoint');
};
@ -166,7 +166,7 @@ module.exports.findAllEndpoints = function(projectRootPath) {
* @returns {Promise} list of full paths to awsm.json files
*/
module.exports.findAllAwsmJsons = function(startPath) {
exports.findAllAwsmJsons = function(startPath) {
return this.readRecursively(startPath, '*awsm.json')
.then(function(jsonPaths) {
return jsonPaths.map(function(jsonPath) {
@ -182,7 +182,7 @@ module.exports.findAllAwsmJsons = function(startPath) {
*
* @param str
*/
module.exports.logIfVerbose = function(str) {
exports.logIfVerbose = function(str) {
if (process.env.JAWS_VERBOSE) {
console.log(str);
}
@ -195,7 +195,7 @@ module.exports.logIfVerbose = function(str) {
* @param contents node Buffer
* @returns {Promise}
*/
module.exports.writeFile = function(filePath, contents) {
exports.writeFile = function(filePath, contents) {
return mkdirpAsync(path.dirname(filePath))
.then(function() {
return fs.writeFileAsync(filePath, contents);
@ -208,7 +208,7 @@ module.exports.writeFile = function(filePath, contents) {
* @returns {string}
*/
module.exports.generateLambdaName = function(awsmJson) {
exports.generateLambdaName = function(awsmJson) {
var handlerName = awsmJson.lambda.cloudFormation.Handler.replace('aws_modules', ''),
resourceAction = handlerName.substr(0, handlerName.lastIndexOf('/'));
@ -226,7 +226,7 @@ module.exports.generateLambdaName = function(awsmJson) {
* @param projectRootPath
* @returns {Promise} list of functionName's
*/
module.exports.getAllLambdaNames = function(projectRootPath) {
exports.getAllLambdaNames = function(projectRootPath) {
var _this = this,
lambdaNames = [];
@ -248,28 +248,28 @@ module.exports.getAllLambdaNames = function(projectRootPath) {
*
* @param projectJawsJson
* @param stage
* @param region
* @param regionName
* @returns {*} region object for stage
*/
module.exports.getProjRegionConfigForStage = function(projectJawsJson, stage, region) {
exports.getProjRegionConfigForStage = function(projectJawsJson, stage, regionName) {
var projectStageObj = projectJawsJson.stages[stage];
var region = projectStageObj.filter(function(regionObj) {
return regionObj.region == region;
return regionObj.region == regionName;
});
if (!region || region.length == 0) {
throw new JawsError('Could not find region ' + region, JawsError.errorCodes.UNKNOWN);
throw new JawsError('Could not find region ' + regionName, JawsError.errorCodes.UNKNOWN);
}
if (region.length > 1) {
throw new JawsError('Multiple regions named ' + region, JawsError.errorCodes.UNKNOWN);
throw new JawsError('Multiple regions named ' + regionName, JawsError.errorCodes.UNKNOWN);
}
return region[0];
};
module.exports.dirExistsSync = function(path) {
exports.dirExistsSync = function(path) {
try {
var stats = fs.lstatSync(path);
return stats.isDirectory();
@ -279,7 +279,7 @@ module.exports.dirExistsSync = function(path) {
}
};
module.exports.fileExistsSync = function(path) {
exports.fileExistsSync = function(path) {
try {
var stats = fs.lstatSync(path);
return stats.isFile();
@ -289,7 +289,7 @@ module.exports.fileExistsSync = function(path) {
}
};
module.exports.readAndParseJsonSync = function(path) {
exports.readAndParseJsonSync = function(path) {
return JSON.parse(fs.readFileSync(path));
};
@ -306,4 +306,19 @@ exports.npmInstall = function(dir) {
}
process.chdir(cwd);
};
};
exports.generateResourcesCf = function(projRootPath, projName, stage, region, notificationEmail) {
var cfTemplate = require('../templates/resources-cf');
cfTemplate.Parameters.aaProjectName.Default = projName;
cfTemplate.Parameters.aaProjectName.AllowedValues = [projName];
cfTemplate.Parameters.aaStage.Default = stage;
cfTemplate.Parameters.aaDataModelPrefix.Default = stage; //to simplify bootstrap use same stage
cfTemplate.Parameters.aaNotficationEmail.Default = notificationEmail;
cfTemplate.Description = projName + " resources";
return this.writeFile(
path.join(projRootPath, 'cloudformation', stage, region, 'resources-cf.json'),
JSON.stringify(cfTemplate, null, 2)
);
};

View File

@ -47,7 +47,6 @@
"insert-module-globals": "^6.5.2",
"jaws-api-gateway-client": "0.11.0",
"keypress": "^0.2.1",
"minimist": "^1.2.0",
"mkdirp-then": "^1.1.0",
"moment": "^2.10.6",
"node-uuid": "^1.4.2",

View File

@ -73,7 +73,7 @@ describe('Test "new stage/region" command', function() {
it('Create New region', function(done) {
this.timeout(0);
CmdNewStageRegion.run(JAWS, 'region', tempStage, tempRegion2, false)
CmdNewStageRegion.run(JAWS, 'region', tempStage, tempRegion2, config.regionBucket, false)
.then(function() {
var jawsJson = require(path.join(process.cwd(), '../jaws.json'));
var region = false;