mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
263 lines
7.4 KiB
JavaScript
263 lines
7.4 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Action: VersionLambda
|
|
*/
|
|
|
|
const JawsPlugin = require('../../JawsPlugin'),
|
|
JawsError = require('../../jaws-error'),
|
|
JawsCLI = require('../../utils/cli'),
|
|
BbPromise = require('bluebird'),
|
|
path = require('path'),
|
|
JawsUtils = require('../../utils/index');
|
|
|
|
let fs = require('fs');
|
|
BbPromise.promisifyAll(fs);
|
|
|
|
class FunctionVersion extends JawsPlugin {
|
|
|
|
/**
|
|
* @param Jaws class object
|
|
* @param config object
|
|
*/
|
|
|
|
constructor(Jaws, config) {
|
|
super(Jaws, config);
|
|
}
|
|
|
|
/**
|
|
* Define your plugins name
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
static getName() {
|
|
return 'jaws.core.' + FunctionVersion.name;
|
|
}
|
|
|
|
/**
|
|
* @returns {Promise} upon completion of all registrations
|
|
*/
|
|
|
|
registerActions() {
|
|
this.Jaws.addAction(this.functionVersion.bind(this), {
|
|
handler: 'functionVersion',
|
|
description: `Version functions at specified paths, or ALL functions
|
|
usage: jaws function version [options]... [paths|ALL]...
|
|
|
|
ex:
|
|
jaws function version ./slss_modules/greetings/hello
|
|
jaws function version`,
|
|
context: 'function',
|
|
contextAction: 'version',
|
|
options: [
|
|
{
|
|
option: 'stage',
|
|
shortcut: 's',
|
|
description: 'Optional if only one stage is defined in project'
|
|
},
|
|
{
|
|
option: 'region',
|
|
shortcut: 'r',
|
|
description: 'Optional. Default is to version lambda in all regions defined in stage'
|
|
},
|
|
{
|
|
option: 'nonInteractive',
|
|
shortcut: 'i',
|
|
description: 'Optional - Turn off CLI interactivity if true. Default: false'
|
|
}
|
|
],
|
|
});
|
|
return BbPromise.resolve();
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param stage Optional if only one stage is defined in project
|
|
* @param region Optional. Default is to version lambda in all regions defined in stage
|
|
* @param lambdaPaths [] optional abs or rel (to cwd) paths to lambda dirs. If ommitted versions lambda @ cwd
|
|
* @returns {Promise.<Array>}
|
|
*/
|
|
functionVersion(event) {
|
|
let _this = this;
|
|
let evt = {};
|
|
_this.evt = {};
|
|
|
|
// If CLI, parse arguments
|
|
if (_this.Jaws.cli) {
|
|
event = _this.Jaws.cli.options;
|
|
event.paths = _this.Jaws.cli.params;
|
|
} else {
|
|
_this.Jaws._interactive = false;
|
|
}
|
|
|
|
_this.evt.stage = event.stage ? event.stage : null;
|
|
_this.evt.regions = event.region ? [event.region] : [];
|
|
_this.evt.noExeCf = (event.noExeCf == true || event.noExeCf == 'true');
|
|
_this.evt.paths = event.paths ? event.paths : [];
|
|
_this.evt.lambdaLogicalIdsToVersion = [];
|
|
|
|
// Flow
|
|
return _this.Jaws.validateProject()
|
|
.bind(_this)
|
|
.then(_this._promptStage)
|
|
.then(_this._validateAndPrepare)
|
|
.then(_this._setLambdaLogicalIds)
|
|
.then(_this._publishVersionInRegions);
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @returns {Promise}
|
|
* @private
|
|
*/
|
|
_promptStage(evt) {
|
|
|
|
let _this = this;
|
|
let stages = Object.keys(_this.Jaws._projectJson.stages);
|
|
|
|
// Skip if non-interactive or stage provided
|
|
if (!_this.Jaws._interactive || _this.evt.stage) return evt;
|
|
|
|
// if project has 1 stage, skip prompt
|
|
if (stages.length === 1) {
|
|
_this.evt.stage = stages[0];
|
|
return evt;
|
|
}
|
|
|
|
// Create Choices
|
|
let choices = [];
|
|
for (let i = 0; i < stages.length; i++) {
|
|
choices.push({
|
|
key: '',
|
|
value: stages[i],
|
|
label: stages[i],
|
|
});
|
|
}
|
|
|
|
// Show prompt
|
|
return _this.selectInput('Function Version - Choose a stage: ', choices, false)
|
|
.then(results => {
|
|
_this.evt.stage = results[0].value;
|
|
return evt;
|
|
});
|
|
}
|
|
|
|
|
|
_validateAndPrepare(evt) {
|
|
let _this = this;
|
|
|
|
// non interactive validation
|
|
if (!_this.Jaws._interactive) {
|
|
|
|
// Check API Keys
|
|
if (!_this.Jaws._awsProfile) {
|
|
if (!_this.Jaws._awsAdminKeyId || !_this.Jaws._awsAdminSecretKey) {
|
|
return BbPromise.reject(new JawsError('Missing AWS Profile and/or API Key and/or AWS Secret Key'));
|
|
}
|
|
}
|
|
// Check Params
|
|
if (!_this.evt.stage) {
|
|
return BbPromise.reject(new JawsError('Missing stage'));
|
|
}
|
|
|
|
// Check paths
|
|
if (!_this.evt.paths.length) {
|
|
return BbPromise.reject(new JawsError('One or multiple paths are required'));
|
|
}
|
|
}
|
|
|
|
// validate stage: make sure stage exists
|
|
if (!_this.Jaws._projectJson.stages[_this.evt.stage]) {
|
|
return BbPromise.reject(new JawsError('Stage ' + _this.evt.stage + ' does not exist in your project', JawsError.errorCodes.UNKNOWN));
|
|
}
|
|
|
|
// If no region specified, deploy to all regions in stage
|
|
if (!_this.evt.regions.length) {
|
|
_this.evt.regions = _this.Jaws._projectJson.stages[_this.evt.stage].map(rCfg => {
|
|
return rCfg.region;
|
|
});
|
|
}
|
|
|
|
JawsUtils.jawsDebug('Queued regions: ' + _this.evt.regions);
|
|
|
|
// Get full paths using the getFunctions() utility
|
|
if (_this.Jaws.cli) {
|
|
if (!_this.evt.paths || !_this.evt.paths.length) {
|
|
|
|
// If CLI and no paths, get full paths from CWD
|
|
return JawsUtils.getFunctions(process.cwd(), null)
|
|
.then(function(functions) {
|
|
|
|
if (!functions.length) return BbPromise.reject(new JawsError('No Functions Found', JawsError.errorCodes.UNKNOWN));
|
|
|
|
_this.evt.functions = functions;
|
|
return evt;
|
|
});
|
|
}
|
|
}
|
|
|
|
// Otherwise, resolve full paths
|
|
return JawsUtils.getFunctions(_this.Jaws._projectRootPath, _this.evt.paths)
|
|
.then(function(functions) {
|
|
_this.evt.functions = functions;
|
|
return evt;
|
|
});
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param lambdaPaths [] optional abs or rel (to cwd) paths to lambda dirs. If ommitted deploys lambda @ cwd
|
|
* @return {Promise}
|
|
* @private
|
|
*/
|
|
_setLambdaLogicalIds(evt) {
|
|
|
|
let _this = this;
|
|
|
|
JawsUtils.jawsDebug('publishing version for stage:', _this.evt.stage);
|
|
|
|
_this.evt.lambdaLogicalIdsToVersion = _this.evt.functions.map(awsmJson => {
|
|
return awsmJson.name;
|
|
});
|
|
|
|
JawsUtils.jawsDebug('setting _lambdaLogicalIdsToVersion', _this.evt.lambdaLogicalIdsToVersion);
|
|
|
|
return evt;
|
|
}
|
|
|
|
_publishVersionInRegions(evt) {
|
|
let _this = this;
|
|
|
|
JawsCLI.log('Publishing the reqeusted function versions to the requested regions...');
|
|
|
|
_this.evt.regions.forEach(region => {
|
|
|
|
let awsConfig = {
|
|
region : region,
|
|
profile: _this._awsProfile,
|
|
};
|
|
|
|
let CF = require('../../utils/aws/CloudFormation')(awsConfig);
|
|
let Lambda = require('../../utils/aws/Lambda')(awsConfig);
|
|
|
|
let lStackName = CF.sGetLambdasStackName(_this.evt.stage, _this.Jaws._projectJson.name);
|
|
|
|
return CF.sGetLambdaResourceSummaries(lStackName)
|
|
.then(lambdaSummaries => {
|
|
return CF.sGetLambdaPhysicalsFromLogicals(_this.evt.lambdaLogicalIdsToVersion, lambdaSummaries);
|
|
})
|
|
.then(lambdaNamesToVersion => {
|
|
return Lambda.sPublishVersions(lambdaNamesToVersion);
|
|
})
|
|
.then(function(versionedLambdas){
|
|
JawsCLI.log('Successfully published the requested function versions to the ' + region + ' region:');
|
|
return versionedLambdas;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = FunctionVersion;
|