mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
376 lines
9.9 KiB
JavaScript
376 lines
9.9 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* JAWS Command: dash
|
|
*/
|
|
|
|
var JawsError = require('../jaws-error'),
|
|
JawsCli = require('../utils/cli'),
|
|
Promise = require('bluebird'),
|
|
fs = require('fs'),
|
|
os = require('os'),
|
|
path = require('path'),
|
|
chalk = require('chalk'),
|
|
utils = require('../utils/index'),
|
|
Tag = require('./Tag'),
|
|
CMDdeployLambda = require('./DeployLambda'),
|
|
CMDdeployEndpoint = require('./DeployEndpoint');
|
|
|
|
/**
|
|
* Run
|
|
* @param JAWS
|
|
* @param stage
|
|
* @param region
|
|
* @param allTagged
|
|
* @returns {Promise}
|
|
*/
|
|
|
|
module.exports.run = function(JAWS, stage, region, allTagged) {
|
|
let command = new CMD(JAWS, stage, region, allTagged);
|
|
return command.run();
|
|
};
|
|
|
|
/**
|
|
* CMD Class
|
|
* @param JAWS
|
|
* @param stage
|
|
* @param region
|
|
* @param allTagged
|
|
* @constructor
|
|
*/
|
|
|
|
function CMD(JAWS, stage, region, allTagged) {
|
|
this._JAWS = JAWS;
|
|
this._allTagged = allTagged || false;
|
|
this._stage = stage || null;
|
|
this._regions = region ? [region] : [];
|
|
this._choices = [];
|
|
}
|
|
|
|
/**
|
|
* CMD: Run
|
|
*/
|
|
|
|
CMD.prototype.run = Promise.method(function() {
|
|
|
|
let _this = this;
|
|
_this._report = {
|
|
selectedLambdas: 0,
|
|
selectedEndpoints: 0,
|
|
};
|
|
|
|
return _this._JAWS.validateProject()
|
|
.bind(_this)
|
|
.then(function() {
|
|
|
|
// If !allTagged, Show Dashboard
|
|
|
|
if (!_this._allTagged) {
|
|
return Promise.try(function() {
|
|
})
|
|
.bind(_this)
|
|
.then(_this._prepareResources)
|
|
.then(_this._prepareSummary)
|
|
.then(_this._renderDash)
|
|
.then(function(selectedResources) {
|
|
|
|
_this._resources = selectedResources;
|
|
if (!_this._resources.length) {
|
|
return false;
|
|
}
|
|
return _this._choices;
|
|
})
|
|
.each(function(resource) {
|
|
let toggled = (!!resource.toggled || false);
|
|
if (resource.type === 'lambda') {
|
|
if (toggled) _this._report.selectedLambdas++;
|
|
return Tag.tag('lambda', resource.value, !toggled);
|
|
} else if (resource.type === 'endpoint') {
|
|
if (toggled) _this._report.selectedEndpoints++;
|
|
return Tag.tag('endpoint', resource.value, !toggled);
|
|
}
|
|
});
|
|
}
|
|
})
|
|
.then(_this._promptStage)
|
|
.then(_this._promptRegion)
|
|
.then(function() {
|
|
|
|
// Status
|
|
JawsCli.log(chalk.white('-------------------------------------------'));
|
|
JawsCli.log(chalk.white(' Dashboard: Deploying Lambdas...'));
|
|
JawsCli.log(chalk.white('-------------------------------------------'));
|
|
|
|
if (!_this._allTagged && !_this._report.selectedLambdas) {
|
|
return JawsCli.log(chalk.white('No selected Lambdas to deploy.'));
|
|
}
|
|
|
|
return CMDdeployLambda.run(
|
|
_this._JAWS,
|
|
_this._stage,
|
|
(_this._regions.length > 1 ? null : _this._regions[0]),
|
|
true);
|
|
})
|
|
.then(function() {
|
|
|
|
// Status
|
|
JawsCli.log(chalk.white('-------------------------------------------'));
|
|
JawsCli.log(chalk.white(' Dashboard: Deploying Endpoints...'));
|
|
JawsCli.log(chalk.white('-------------------------------------------'));
|
|
|
|
if (!_this._allTagged && !_this._report.selectedEndpoints) {
|
|
return JawsCli.log(chalk.white('No selected Endpoints to deploy.'));
|
|
}
|
|
|
|
return CMDdeployEndpoint.run(
|
|
_this._JAWS,
|
|
_this._stage,
|
|
_this._regions,
|
|
true);
|
|
})
|
|
.then(function() {
|
|
|
|
// Status
|
|
JawsCli.log(chalk.white('-------------------------------------------'));
|
|
JawsCli.log(chalk.white(' Dashboard: Deployments Completed'));
|
|
JawsCli.log(chalk.white('-------------------------------------------'));
|
|
});
|
|
});
|
|
|
|
/**
|
|
* CMD: Prepare Resources
|
|
*/
|
|
|
|
CMD.prototype._prepareResources = Promise.method(function() {
|
|
let _this = this;
|
|
|
|
return utils.findAllAwsmJsons(path.join(_this._JAWS._meta.projectRootPath, 'aws_modules'))
|
|
.then(function(jsonPaths) {
|
|
|
|
let hybrids = [];
|
|
let lambdas = [];
|
|
|
|
// Fetch and prepare json modules
|
|
for (let i = 0; i < jsonPaths.length; i++) {
|
|
|
|
// Add modules
|
|
let json = require(jsonPaths[i]);
|
|
let module = {};
|
|
|
|
// Add Lambda
|
|
if (json.lambda) {
|
|
|
|
module.lambda = {
|
|
key: ' L) ',
|
|
value: jsonPaths[i],
|
|
type: 'lambda',
|
|
label: utils.generateLambdaName(json),
|
|
};
|
|
|
|
// Create path
|
|
let paths = jsonPaths[i].split('/');
|
|
paths = paths[paths.length - 3] + '/' + paths[paths.length - 2];
|
|
module.lambda.path = chalk.grey(paths);
|
|
}
|
|
|
|
// Add Endpoint
|
|
if (json.apiGateway) {
|
|
module.endpoint = {
|
|
key: ' E) ',
|
|
value: jsonPaths[i],
|
|
type: 'endpoint',
|
|
label: '/' + json.apiGateway.cloudFormation.Path
|
|
+ ' - ' + json.apiGateway.cloudFormation.Method,
|
|
};
|
|
|
|
// Create path
|
|
let paths = jsonPaths[i].split('/');
|
|
paths = paths[paths.length - 3] + '/' + paths[paths.length - 2];
|
|
module.endpoint.path = chalk.grey(paths);
|
|
}
|
|
|
|
if (module.lambda && module.endpoint) hybrids.push(module);
|
|
if (module.lambda && !module.endpoint) lambdas.push(module);
|
|
}
|
|
|
|
// Sort hybrids by label/paths
|
|
hybrids.sort(function(a, b) {
|
|
return (a.label < b.label) ? -1 : (a.label > b.label) ? 1 : 0;
|
|
});
|
|
|
|
// Sort lambdas by label
|
|
lambdas.sort(function(a, b) {
|
|
return (a.label < b.label) ? -1 : (a.label > b.label) ? 1 : 0;
|
|
});
|
|
|
|
// Add Lambdas back in
|
|
let modules = lambdas.concat(hybrids);
|
|
|
|
// Prepare Choices
|
|
for (var i = 0; i < modules.length; i++) {
|
|
|
|
if (modules[i].lambda || modules[i].endpoint) {
|
|
_this._choices.push({
|
|
spacer: modules[i].lambda.path ? modules[i].lambda.path : modules[i].endpoint.path,
|
|
});
|
|
}
|
|
if (modules[i].lambda) {
|
|
_this._choices.push(modules[i].lambda);
|
|
}
|
|
if (modules[i].endpoint) {
|
|
_this._choices.push(modules[i].endpoint);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
/**
|
|
* CMD: Prepare Summary
|
|
*/
|
|
|
|
CMD.prototype._prepareSummary = Promise.method(function() {
|
|
|
|
let _this = this;
|
|
let lambdaCount = 0;
|
|
let endpointCount = 0;
|
|
|
|
// Count Lambdas and Endpoints
|
|
for (var i = 0; i < _this._choices.length; i++) {
|
|
if (_this._choices[i].type === 'lambda') lambdaCount++;
|
|
if (_this._choices[i].type === 'endpoint') endpointCount++;
|
|
}
|
|
|
|
_this._summary = 'Dashboard for project "' + _this._JAWS._meta.projectJson.name + '"' + os.EOL
|
|
+ chalk.white.bold(' -------------------------------------------') + os.EOL
|
|
+ chalk.white(' Project Summary') + os.EOL
|
|
+ chalk.white.bold(' -------------------------------------------') + os.EOL
|
|
+ chalk.white(' Stages: ' + os.EOL);
|
|
|
|
// Add Stage Data
|
|
for (var stage in _this._JAWS._meta.projectJson.stages) {
|
|
|
|
_this._summary = _this._summary
|
|
+ chalk.white(' ' + stage + ' ');
|
|
|
|
for (var i = 0; i < _this._JAWS._meta.projectJson.stages[stage].length; i++) {
|
|
_this._summary = _this._summary
|
|
+ chalk.grey(_this._JAWS._meta.projectJson.stages[stage][i].region + ' ')
|
|
}
|
|
|
|
_this._summary = _this._summary + os.EOL;
|
|
}
|
|
|
|
_this._summary = _this._summary
|
|
+ chalk.white(' Lambdas: ' + lambdaCount) + os.EOL
|
|
+ chalk.white(' Endpoints: ' + endpointCount) + os.EOL
|
|
+ chalk.white.bold(' -------------------------------------------') + os.EOL
|
|
+ chalk.white(' Select Resources To Deploy') + os.EOL
|
|
+ chalk.white.bold(' -------------------------------------------');
|
|
});
|
|
|
|
/**
|
|
* CMD: Render Dash
|
|
*/
|
|
|
|
CMD.prototype._renderDash = Promise.method(function() {
|
|
|
|
let _this = this;
|
|
|
|
JawsCli.log(_this._summary);
|
|
|
|
return JawsCli.select(
|
|
null,
|
|
_this._choices,
|
|
true,
|
|
' Deploy Selected -->');
|
|
});
|
|
|
|
/**
|
|
* CMD: Prompt: Stage
|
|
*/
|
|
|
|
CMD.prototype._promptStage = Promise.method(function() {
|
|
|
|
let _this = this;
|
|
|
|
// If stage exists, skip
|
|
if (_this._stage) return;
|
|
|
|
let stages = Object.keys(_this._JAWS._meta.projectJson.stages);
|
|
|
|
// Check if project has stages
|
|
if (!stages.length) {
|
|
throw new JawsError('This project has no stages');
|
|
}
|
|
|
|
// If project only has 1 stage, skip prompt
|
|
if (stages.length === 1) {
|
|
_this._stage = stages[0];
|
|
return;
|
|
}
|
|
|
|
// Create Choices
|
|
let choices = [];
|
|
for (var i = 0; i < stages.length; i++) {
|
|
choices.push({
|
|
key: (i + 1) + ') ',
|
|
value: stages[i],
|
|
label: stages[i],
|
|
});
|
|
}
|
|
|
|
return JawsCli.select('Choose a stage: ', choices, false)
|
|
.then(function(results) {
|
|
_this._stage = results[0].value;
|
|
});
|
|
});
|
|
|
|
/**
|
|
* CMD: Prompt: Region
|
|
*/
|
|
|
|
CMD.prototype._promptRegion = Promise.method(function() {
|
|
|
|
let _this = this;
|
|
|
|
// If region exists, skip
|
|
if (_this._regions.length) return;
|
|
|
|
let regions = _this._JAWS._meta.projectJson.stages[_this._stage].map(function(s) {
|
|
return s.region;
|
|
});
|
|
|
|
// Check if stage has regions
|
|
if (!regions.length) {
|
|
throw new JawsError('This stage has no regions');
|
|
}
|
|
|
|
_this._regions = regions;
|
|
|
|
// If stage only has 1 region, use it and skip prompt
|
|
if (regions.length === 1) return;
|
|
|
|
// Create Choices
|
|
let choices = [];
|
|
for (var i = 0; i < _this._regions.length; i++) {
|
|
choices.push({
|
|
key: '',
|
|
value: _this._regions[i],
|
|
label: _this._regions[i],
|
|
});
|
|
}
|
|
|
|
choices.push({
|
|
key: '',
|
|
value: 'all regions',
|
|
label: 'all regions',
|
|
});
|
|
|
|
return JawsCli.select('Choose a region within this stage: ', choices, false)
|
|
.then(function(results) {
|
|
if (results[0].value !== 'all regions') {
|
|
_this._regions = [results[0].value];
|
|
}
|
|
});
|
|
});
|