serverless/lib/actions/VariablesSet.js

253 lines
7.7 KiB
JavaScript

'use strict';
/**
* Action: VariablesSet
* - Defines a new variable that can be used in any of your project's configuration files
*/
module.exports = function(S) {
const path = require('path'),
replaceall = require('replaceall'),
SUtils = S.utils,
SError = require(S.getServerlessPath('Error')),
SCli = require(S.getServerlessPath('utils/cli')),
BbPromise = require('bluebird'),
_ = require('lodash'),
async = require('async');
class VariablesSet extends S.classes.Plugin {
/**
* Define your plugins name
*/
static getName() {
return 'serverless.core.' + this.name;
}
/**
* @returns {Promise} upon completion of all registrations
*/
registerActions() {
S.addAction(this.variablesSet.bind(this), {
handler: 'variablesSet',
description: 'Defines a new variable that can be used in any of your project\'s configuration files. Usage: serverless variables set',
context: 'variables',
contextAction: 'set',
options: [
{
option: 'type',
shortcut: 't',
description: 'variable type (common, stage or region)'
},
{
option: 'region',
shortcut: 'r',
description: 'region you want to set the variable in'
},
{
option: 'stage',
shortcut: 's',
description: 'stage you want to set the variable in'
},
{
option: 'key',
shortcut: 'k',
description: 'the key of the variable you want to set'
},
{
option: 'value',
shortcut: 'v',
description: 'the value of the variable you want to set'
}
]
});
return BbPromise.resolve();
}
/**
* Action
*/
variablesSet(evt) {
let _this = this;
_this.evt = evt;
return _this._prompt()
.bind(_this)
.then(_this._validateAndPrepare)
.then(_this._setVariable)
.then(function() {
SCli.log('Successfully set variable: ' + _this.evt.options.key);
return _this.evt;
});
}
/**
* Prompt key, value, stage and region
*/
_prompt() {
let _this = this;
if (!S.config.interactive) return BbPromise.resolve();
return BbPromise.try(function() {
// Skip if key is provided already
if (_this.evt.options.key) return;
let prompts = {
properties: {}
};
prompts.properties.key = {
description: 'Enter variable key to set a value to: '.yellow,
required: true
};
return _this.cliPromptInput(prompts, { key: _this.evt.options.key })
.then(function(answers) {
_this.evt.options.key = answers.key;
});
})
.then(function() {
// Skip if value is provided already
if (_this.evt.options.value) return;
let prompts = {
properties: {}
};
prompts.properties.value = {
description: 'Enter variable value to set a value to: '.yellow,
required: true
};
return _this.cliPromptInput(prompts, { value: _this.evt.options.value })
.then(function(answers) {
_this.evt.options.value = answers.value;
});
})
.then(function() {
// Allow to dismiss region to set stage variables
const selection = [
{key:"1) ", value:"common", label:"Common"},
{key:"2) ", value:"stage", label:"Stage"},
{key:"3) ", value:"region", label:"Region"}
];
if (_.indexOf(['common','stage','region'], _this.evt.options.type) !== -1) {
return BbPromise.resolve();
}
return _this.cliPromptSelect('Select variable type: ', selection, false)
.spread(function(selectType) {
_this.evt.options.type = selectType.value;
return BbPromise.resolve();
});
})
.then(function() {
if (_this.evt.options.type === 'common') {
return BbPromise.resolve();
}
return _this.cliPromptSelectStage('Select a stage to set your variable in: ', _this.evt.options.stage, false)
.then(stage => {
_this.evt.options.stage = stage;
})
})
.then(function() {
if (_this.evt.options.type !== "region") {
return BbPromise.resolve();
}
return _this.cliPromptSelectRegion('Select a region to set variable in: ', false, true, _this.evt.options.region, _this.evt.options.stage)
.then(region => {
_this.evt.options.region = region;
});
});
}
/**
* Validate all data from event, interactive CLI or non interactive CLI
* and prepare data
*/
_validateAndPrepare() {
let _this = this;
// non interactive validation
if (!S.config.interactive) {
// Check Params
const paramsOk = (!!_this.evt.options.type && !!_this.evt.options.key && !!_this.evt.options.value) &&
(_this.evt.options.type === 'common' ||
(_this.evt.options.type === 'stage' && !!_this.evt.options.stage) ||
(_this.evt.options.type === 'region' && !!_this.evt.options.stage && !!_this.evt.options.region));
if (!paramsOk) {
return BbPromise.reject(new SError('Wrong parameter combination or missing key/value. See --help.'));
}
}
// Validate stage: make sure stage exists
if ((_this.evt.options.type !== 'common') && !S.getProject().validateStageExists(_this.evt.options.stage) && _this.evt.options.stage != 'local') {
return BbPromise.reject(new SError('Stage ' + _this.evt.options.stage + ' does not exist in your project'));
}
// Skip the next validation if stage is 'local' & region is 'all'
if (_this.evt.options.type === 'region' && _this.evt.options.stage != 'local' && _this.evt.options.region != 'all') {
// validate region: make sure region exists in stage
if (!S.getProject().validateRegionExists(_this.evt.options.stage, _this.evt.options.region)) {
return BbPromise.reject(new SError('Region "' + _this.evt.options.region + '" does not exist in stage "' + _this.evt.options.stage + '"'));
}
}
}
/**
* Set the variable and save it
*/
_setVariable() {
let _this = this,
type = this.evt.options.type,
stage = this.evt.options.stage,
region = this.evt.options.region,
project = S.getProject();
let setVariableHelper = (region) => {
let v = {};
v[_this.evt.options.key] = _this.evt.options.value;
region.addVariables(v);
region.save();
};
let v = {};
v[_this.evt.options.key] = _this.evt.options.value;
switch (type) {
case 'common':
project.addVariables(v);
project.save();
break;
case 'stage':
project.getStage(stage).addVariables(v);
project.getStage(stage).save();
break;
case 'region':
S.getProject().getRegion(stage, region).addVariables(v);
S.getProject().getRegion(stage, region).save();
break;
}
}
}
return( VariablesSet );
};