CodePackageLambdaNodejs: start work on this

This commit is contained in:
Austen Collins 2015-11-17 21:23:18 -08:00
parent 9c81468260
commit 53fb4e6b3a
12 changed files with 421 additions and 422 deletions

View File

@ -2,17 +2,23 @@
/**
* Action: Code Package: Lambda: Nodejs
* - Collects and optimizes Lambda code in a temp folder
* - Accepts one function
* - Collects and optimizes the function's Lambda code in a temp folder
*/
const JawsPlugin = require('../../JawsPlugin'),
JawsError = require('../../jaws-error'),
JawsUtils = require('../../utils/index'),
extend = require('util')._extend,
JawsCli = require('../../utils/cli'),
BbPromise = require('bluebird'),
path = require('path'),
fs = require('fs'),
os = require('os');
os = require('os'),
babelify = require('babelify'),
browserify = require('browserify'),
UglifyJS = require('uglify-js'),
wrench = require('wrench'),
Zip = require('node-zip');
// Promisify fs module
BbPromise.promisifyAll(fs);
@ -41,7 +47,7 @@ class CodePackageLambdaNodejs extends JawsPlugin {
registerActions() {
this.Jaws.addAction(this.CodePackageLambdaNodejs.bind(this), {
this.Jaws.addAction(this.codePackageLambdaNodejs.bind(this), {
handler: 'codePackageLambdaNodejs',
description: 'Deploys the code or endpoint of a function, or both'
});
@ -58,89 +64,355 @@ class CodePackageLambdaNodejs extends JawsPlugin {
let _this = this;
_this.evt = evt;
// Load AWS Service Instances
let awsConfig = {
region: _this.evt.deployRegion.region,
accessKeyId: _this.Jaws._awsAdminKeyId,
secretAccessKey: _this.Jaws._awsAdminSecretKey,
};
_this.S3 = require('../../utils/aws/S3')(awsConfig);
// Flow
return BbPromise.try(function() {})
.bind(_this)
.then(_this._validateAndPrepare)
.then(_this._promptStage)
.then(_this._prepareRegions)
.then(_this._deployRegions);
.then(_this._createDistFolder)
.then(_this._package)
}
/**
* Validate And Prepare
* - If CLI, maps CLI input to event object
*/
_validateAndPrepare() {
let _this = this,
lambda;
// Require function config
let functionJson = require(_this.evt.currentFunction);
// Skip Function if it does not have a lambda
try {
lambda = functionJson.cloudFormation.lambda;
} catch(error) {
return Promise.reject(new JawsError(_this.evt.currentFunction + 'does not have a lambda property'));
}
// Validate lambda attributes
if (!lambda.Type
|| !lambda.Properties
|| !lambda.Properties.Runtime
|| !lambda.Properties.Handler) {
return Promise.reject(new JawsError('Missing one of many required lambda attributes'));
}
// Add function path to functionJson
functionJson.path = _this.evt.currentFunction;
// Change function path to object
_this.evt.currentFunction = functionJson;
return BbPromise.resolve();
}
/**
* Create Distribution Folder
*/
_createDistFolder() {
let _this = this;
// If cli, process command line input
if (_this.Jaws.cli) {
// Create dist folder
let d = new Date();
_this.evt.distDir = path.join(os.tmpdir(), _this.evt.currentFunction.name + '@' + d.getTime());
// Add options to evt
_this.evt = _this.Jaws.cli.options;
// Status
JawsCli.log('Lambda Deployer: Packaging "' + _this.evt.currentFunction.name + '"...');
JawsCli.log('Lambda Deployer: Saving in dist dir ' + _this.evt.distDir);
// Add type. Should be first in array
_this.evt.type = _this.Jaws.cli.params[0];
JawsUtils.jawsDebug('copying', _this.Jaws._projectRootPath, 'to', _this.evt.distDir);
// Add function paths. Should be all other array items
_this.Jaws.cli.params.splice(0,1);
_this.evt.functions = _this.Jaws.cli.params;
}
// Validate type
if (!_this.evt.type ||
(_this.evt.type !== 'code' &&
_this.evt.type !== 'endpoint' &&
_this.evt.type !== 'all')
) {
throw new JawsError(`Invalid type. Must be "code", "endpoint", or "all" `);
}
// Validate stage
if (!this.evt.stage) throw new JawsError(`Stage is required`);
// If region specified, add it to regions array for deployment
if (this.evt.region) {
this.evt.regions = [this.evt.region];
delete this.evt.region; // Remove original "region" property for cleanliness
}
// Process noExeCf
this.evt.noExeCf = (this.evt.noExeCf == true || this.evt.noExeCf == 'true');
// Get full function paths relative to project root
if (!_this.evt.functions.length) {
// If no functions, check cwd and resolve that path
return JawsUtils.getFunctions(
_this.Jaws._projectRootPath,
_this.evt.type
)
.then(function(functions) {
// If no functions, throw error
if (!_this.evt.functions.length) {
throw new JawsError(`No function found. Make sure your current working directory is a function.`);
// Copy entire test project to temp folder
let excludePatterns = _this.evt.currentFunction.package.excludePatterns || [];
wrench.copyDirSyncRecursive(
_this.Jaws._projectRootPath,
_this.evt.distDir,
{
exclude: function(name, prefix) {
if (!excludePatterns.length) {
return false;
}
_this.evt.functions = functions;
let relPath = path.join(
prefix.replace(_this.evt.distDir, ''), name);
return excludePatterns.some(sRegex => {
relPath = (relPath.charAt(0) == path.sep) ? relPath.substr(1) : relPath;
let re = new RegExp(sRegex),
matches = re.exec(relPath),
willExclude = (matches && matches.length > 0);
if (willExclude) {
JawsCLI.log(`Lambda Deployer: Excluding ${relPath}`);
}
return willExclude;
});
},
}
);
JawsUtils.jawsDebug('Packaging stage & region:', _this.evt.stage, _this.evt.deployRegion);
// Get ENV file from S3
return _this.S3.sGetEnvFile(
_this.evt.deployRegion.jawsBucket,
_this.Jaws._projectJson.name,
_this.evt.stage
)
.then(function(s3ObjData) {
fs.writeFileSync(
path.join(_this.evt.distDir,'.env'),
s3ObjData.Body);
});
}
/**
* Package
*/
_package() {
let _this = this,
lambda = _this.evt.currentFunction.cloudFormation.lambda,
deferred = false,
targetZipPath = path.join(_this.evt.distDir, 'package.zip'),
optimizeSettings = _this.evt.currentFunction.package.optimize;
if (optimizeSettings.builder) {
deferred = _this._optimizeNodeJs()
.then(optimizedCodeBuffer => {
let envData = fs.readFileSync(path.join(_this.evt.distDir, '.env')),
handlerFileName = lambda.Function.Properties.Handler.split('.')[0],
compressPaths = [
// handlerFileName is the full path lambda file including dir rel to back
{fileName: handlerFileName + '.js', data: optimizedCodeBuffer},
{fileName: '.env', data: envData},
];
compressPaths = compressPaths.concat(_this._generateIncludePaths());
return compressPaths;
});
} else {
// If functions, resolve their paths
return JawsUtils.getFunctions(
_this.Jaws._projectRootPath,
_this.evt.type,
_this.evt.functions
)
.then(function(functions) {
_this.evt.functions = functions;
});
// User chose not to optimize, zip up whatever is in back
optimizeSettings.includePaths = ['.'];
let compressPaths = _this._generateIncludePaths();
deferred = Promise.resolve(compressPaths);
}
return deferred
.then(compressPaths => {
return _this._compress(compressPaths, targetZipPath);
})
.then(zipFilePath => {
return Promise.resolve({awsmFilePath: _this._lambdaAwsmPath, zipFilePath: zipFilePath});
});
}
/**
* Optimize
*/
_optimize() {
let _this = this,
lambda = _this.evt.currentFunction.cloudFormation.lambda;
if (!_this.evt.currentFunction.package.optimize
|| !_this.evt.currentFunction.package.optimize.builder) {
return Promise.reject(new JawsError('Cant optimize for nodejs. lambda jaws.json does not have optimize.builder set'));
}
if (_this.evt.currentFunction.package.optimize.builder.toLowerCase() == 'browserify') {
return _this._browserifyBundle();
} else {
return Promise.reject(new JawsError(`Unsupported builder ${builder}`));
}
}
/**
* Generate Include Paths
*/
_generateIncludePaths() {
let _this = this,
compressPaths = [],
ignore = ['.DS_Store'],
stats,
fullPath;
_this._awsmJson.package.optimize.includePaths.forEach(p => {
try {
fullPath = path.resolve(path.join(_this._distDir, p));
stats = fs.lstatSync(fullPath);
} catch (e) {
console.error('Cant find includePath ', p, e);
throw e;
}
if (stats.isFile()) {
JawsUtils.jawsDebug('INCLUDING', fullPath);
compressPaths.push({fileName: p, data: fs.readFileSync(fullPath)});
} else if (stats.isDirectory()) {
let dirname = path.basename(p);
wrench
.readdirSyncRecursive(fullPath)
.forEach(file => {
// Ignore certain files
for (let i = 0; i < ignore.length; i++) {
if (file.toLowerCase().indexOf(ignore[i]) > -1) return;
}
let filePath = [fullPath, file].join('/');
if (fs.lstatSync(filePath).isFile()) {
let pathInZip = path.join(dirname, file);
JawsUtils.jawsDebug('INCLUDING', pathInZip);
compressPaths.push({fileName: pathInZip, data: fs.readFileSync(filePath)});
}
});
}
});
return compressPaths;
}
/**
* Compress
*/
_compress(compressPaths, targetZipPath) {
let zip = new Zip();
compressPaths.forEach(nc => {
zip.file(nc.fileName, nc.data);
});
let zipBuffer = zip.generate({
type: 'nodebuffer',
compression: 'DEFLATE',
});
if (zipBuffer.length > 52428800) {
Promise.reject(new JawsError(
'Zip file is > the 50MB Lambda deploy limit (' + zipBuffer.length + ' bytes)',
JawsError.errorCodes.ZIP_TOO_BIG)
);
}
fs.writeFileSync(targetZipPath, zipBuffer);
JawsCLI.log(`Lambda Deployer: Compressed code written to ${targetZipPath}`);
return Promise.resolve(targetZipPath);
}
/**
* Browserify the code and return buffer of bundled code
*
* @returns {Promise.Buffer}
* @private
*/
_browserifyBundle() {
let _this = this;
let uglyOptions = {
mangle: true, // @see http://lisperator.net/uglifyjs/compress
compress: {},
};
let b = browserify({
basedir: _this._distDir,
entries: [_this._awsmJson.cloudFormation.lambda.Function.Properties.Handler.split('.')[0] + '.js'],
standalone: 'lambda',
browserField: false, // Setup for node app (copy logic of --node in bin/args.js)
builtins: false,
commondir: false,
ignoreMissing: true, // Do not fail on missing optional dependencies
detectGlobals: true, // Default for bare in cli is true, but we don't care if its slower
insertGlobalVars: { // Handle process https://github.com/substack/node-browserify/issues/1277
//__filename: insertGlobals.lets.__filename,
//__dirname: insertGlobals.lets.__dirname,
process: function() {
},
},
});
if (_this._awsmJson.package.optimize.babel) {
b.transform(babelify);
}
if (_this._awsmJson.package.optimize.transform) {
JawsUtils.jawsDebug('Adding transform', _this._awsmJson.package.optimize.transform);
b.transform(_this._awsmJson.package.optimize.transform);
}
// optimize.exclude
_this._awsmJson.package.optimize.exclude.forEach(file => {
JawsUtils.jawsDebug('EXCLUDING', file);
b.exclude(file);
});
// optimize.ignore
_this._awsmJson.package.optimize.ignore.forEach(file => {
JawsUtils.jawsDebug('IGNORING', file);
b.ignore(file);
});
// Perform Bundle
let bundledFilePath = path.join(_this._distDir, 'bundled.js'); // Save for auditing
let minifiedFilePath = path.join(_this._distDir, 'minified.js'); // Save for auditing
return new Promise(function(resolve, reject) {
b.bundle(function(err, bundledBuf) {
if (err) {
console.error('Error running browserify bundle');
reject(err);
} else {
fs.writeFileSync(bundledFilePath, bundledBuf);
JawsCLI.log(`Lambda Deployer: Bundled file written to ${bundledFilePath}`);
if (_this._awsmJson.package.optimize.minify) {
JawsUtils.jawsDebug('Minifying...');
let result = UglifyJS.minify(bundledFilePath, uglyOptions);
if (!result || !result.code) {
reject(new JawsError('Problem uglifying code'));
}
fs.writeFileSync(minifiedFilePath, result.code);
JawsCLI.log(`Lambda Deployer: Minified file written to ${minifiedFilePath}`);
resolve(result.code);
} else {
resolve(bundledBuf);
}
}
});
});
}
}
module.exports = CodePackageLambdaNodejs;

View File

@ -41,7 +41,7 @@ class CodeProvisionLambdaNodejs extends JawsPlugin {
registerActions() {
this.Jaws.addAction(this.CodeProvisionLambdaNodejs.bind(this), {
this.Jaws.addAction(this.codeProvisionLambdaNodejs.bind(this), {
handler: 'codeProvisionLambdaNodejs',
description: 'Deploys the code or endpoint of a function, or both'
});

View File

@ -11,6 +11,7 @@ const JawsPlugin = require('../../JawsPlugin'),
JawsUtils = require('../../utils/index'),
extend = require('util')._extend,
BbPromise = require('bluebird'),
async = require('async'),
path = require('path'),
fs = require('fs'),
os = require('os');
@ -138,6 +139,7 @@ class FunctionDeploy extends JawsPlugin {
_this.evt.type
)
.then(function(functions) {
// If no functions, throw error
if (!_this.evt.functions.length) {
throw new JawsError(`No function found. Make sure your current working directory is a function.`);
@ -236,14 +238,8 @@ class FunctionDeploy extends JawsPlugin {
})
.each(function(region) {
// Clone evt object keeps us safe when we start doing concurrent operations
let evtClone = extend({}, _this.evt);
// Add Region JSON for the deploy region
evtClone.deployRegion = JawsUtils.getProjRegionConfigForStage(_this.Jaws._projectJson, _this.evt.stage, region);
// Deploy Type
switch(evtClone.type) {
switch(_this.evt.type) {
// Deploy Endpoint only
case "endpoint":
@ -254,6 +250,40 @@ class FunctionDeploy extends JawsPlugin {
// Deploy Code only (lambda)
case "code":
return new BbPromise(function(resolve, reject) {
// Process Functions concurrently
async.eachLimit(_this.evt.functions, 5, function(func, cb) {
// Clone evt object for concurrent operations
let evtClone = extend({}, _this.evt);
// Add Region JSON for the deploy region
evtClone.deployRegion = JawsUtils.getProjRegionConfigForStage(
_this.Jaws._projectJson,
_this.evt.stage,
region
);
// Add Function to event clone
evtClone.currentFunction = func;
return _this.Jaws.actions.codePackageLambdaNodejs(evtClone)
.bind(_this)
.then(_this.Jaws.actions.codeProvisionLambdaNodejs)
.then(function() {
return cb();
})
.catch(function(e) {
return reject(new JawsError(func + ' - ' + e.message));
});
}, function() {
return resolve(_this.evt);
});
});
break;
// Deploy Code then Endpoint

View File

@ -226,327 +226,7 @@ class Deployer {
}
}
class Packager {
constructor(JAWS, stage, region, lambdaAwsmPath) {
this._JAWS = JAWS;
this._lambdaAwsmPath = lambdaAwsmPath;
this._stage = stage;
this._region = region;
this._awsmJson = JawsUtils.readAndParseJsonSync(this._lambdaAwsmPath);
this._distDir = '';
}
/**
*
* @returns {Promise} {awsmFilePath: "", zipFilePath: "/tmp/path/to/blah.zip"}
*/
run() {
let _this = this;
return this._createDistFolder()
.then(function() {
let runtime = _this._awsmJson.cloudFormation.lambda.Function.Properties.Runtime;
switch (runtime) {
case 'nodejs':
return _this._packageNodeJs(runtime);
break;
default:
return Promise.reject(new JawsError(`Unsupported lambda runtime ${runtime}`, JawsError.errorCodes.UNKNOWN));
break;
}
});
}
/**
* Create Dist Folder (for an individual lambda)
*
* @returns {Promise}
* @private
*/
_createDistFolder() {
let _this = this;
// Create dist folder
let d = new Date();
_this._distDir = path.join(os.tmpdir(), this._awsmJson.name + '@' + d.getTime());
// Status
JawsCLI.log('Lambda Deployer: Packaging "' + this._awsmJson.name + '"...');
JawsCLI.log('Lambda Deployer: Saving in dist dir ' + _this._distDir);
JawsUtils.jawsDebug('copying', _this._JAWS._projectRootPath, 'to', _this._distDir);
// Copy entire test project to temp folder
_this._excludePatterns = _this._awsmJson.package.excludePatterns || [];
wrench.copyDirSyncRecursive(
_this._JAWS._projectRootPath,
_this._distDir,
{
exclude: function(name, prefix) {
if (!_this._excludePatterns.length) {
return false;
}
let relPath = path.join(
prefix.replace(_this._distDir, ''), name);
return _this._excludePatterns.some(sRegex => {
relPath = (relPath.charAt(0) == path.sep) ? relPath.substr(1) : relPath;
let re = new RegExp(sRegex),
matches = re.exec(relPath),
willExclude = (matches && matches.length > 0);
if (willExclude) {
JawsCLI.log(`Lambda Deployer: Excluding ${relPath}`);
}
return willExclude;
});
},
}
);
JawsUtils.jawsDebug('Packaging stage & region:', _this._stage, _this._region);
// Get ENV file from S3
return _this._JAWS.getEnvFile(_this._region, _this._stage)
.then(function(s3ObjData) {
fs.writeFileSync(path.join(_this._distDir, '.env'), s3ObjData.Body);
});
}
/**
*
* @returns {Promise} {awsmFilePath: "", zipFilePath: "/tmp/blah.zip"}
* @private
*/
_packageNodeJs() {
let _this = this,
deferred = false,
targetZipPath = path.join(this._distDir, 'package.zip'),
optimizeSettings = _this._awsmJson.package.optimize;
if (optimizeSettings.builder) {
deferred = _this._optimizeNodeJs()
.then(optimizedCodeBuffer => {
let envData = fs.readFileSync(path.join(_this._distDir, '.env')),
handlerFileName = _this._awsmJson.cloudFormation.lambda.Function.Properties.Handler.split('.')[0],
compressPaths = [
// handlerFileName is the full path lambda file including dir rel to back
{fileName: handlerFileName + '.js', data: optimizedCodeBuffer},
{fileName: '.env', data: envData},
];
compressPaths = compressPaths.concat(_this._generateIncludePaths());
return compressPaths;
});
} else {
// User chose not to optimize, zip up whatever is in back
optimizeSettings.includePaths = ['.'];
let compressPaths = _this._generateIncludePaths();
deferred = Promise.resolve(compressPaths);
}
return deferred
.then(compressPaths => {
return _this._compressCode(compressPaths, targetZipPath);
})
.then(zipFilePath => {
return Promise.resolve({awsmFilePath: _this._lambdaAwsmPath, zipFilePath: zipFilePath});
});
}
/**
*
* @returns {*}
* @private
*/
_optimizeNodeJs() {
let _this = this;
if (!_this._awsmJson.package.optimize
|| !_this._awsmJson.package.optimize.builder) {
return Promise.reject(new JawsError('Cant optimize for nodejs. lambda jaws.json does not have optimize.builder set'));
}
if (_this._awsmJson.package.optimize.builder.toLowerCase() == 'browserify') {
return _this._browserifyBundle();
} else {
return Promise.reject(new JawsError(`Unsupported builder ${builder}`));
}
}
/**
* Browserify the code and return buffer of bundled code
*
* @returns {Promise.Buffer}
* @private
*/
_browserifyBundle() {
let _this = this;
let uglyOptions = {
mangle: true, // @see http://lisperator.net/uglifyjs/compress
compress: {},
};
let b = browserify({
basedir: _this._distDir,
entries: [_this._awsmJson.cloudFormation.lambda.Function.Properties.Handler.split('.')[0] + '.js'],
standalone: 'lambda',
browserField: false, // Setup for node app (copy logic of --node in bin/args.js)
builtins: false,
commondir: false,
ignoreMissing: true, // Do not fail on missing optional dependencies
detectGlobals: true, // Default for bare in cli is true, but we don't care if its slower
insertGlobalVars: { // Handle process https://github.com/substack/node-browserify/issues/1277
//__filename: insertGlobals.lets.__filename,
//__dirname: insertGlobals.lets.__dirname,
process: function() {
},
},
});
if (_this._awsmJson.package.optimize.babel) {
b.transform(babelify);
}
if (_this._awsmJson.package.optimize.transform) {
JawsUtils.jawsDebug('Adding transform', _this._awsmJson.package.optimize.transform);
b.transform(_this._awsmJson.package.optimize.transform);
}
// optimize.exclude
_this._awsmJson.package.optimize.exclude.forEach(file => {
JawsUtils.jawsDebug('EXCLUDING', file);
b.exclude(file);
});
// optimize.ignore
_this._awsmJson.package.optimize.ignore.forEach(file => {
JawsUtils.jawsDebug('IGNORING', file);
b.ignore(file);
});
// Perform Bundle
let bundledFilePath = path.join(_this._distDir, 'bundled.js'); // Save for auditing
let minifiedFilePath = path.join(_this._distDir, 'minified.js'); // Save for auditing
return new Promise(function(resolve, reject) {
b.bundle(function(err, bundledBuf) {
if (err) {
console.error('Error running browserify bundle');
reject(err);
} else {
fs.writeFileSync(bundledFilePath, bundledBuf);
JawsCLI.log(`Lambda Deployer: Bundled file written to ${bundledFilePath}`);
if (_this._awsmJson.package.optimize.minify) {
JawsUtils.jawsDebug('Minifying...');
let result = UglifyJS.minify(bundledFilePath, uglyOptions);
if (!result || !result.code) {
reject(new JawsError('Problem uglifying code'));
}
fs.writeFileSync(minifiedFilePath, result.code);
JawsCLI.log(`Lambda Deployer: Minified file written to ${minifiedFilePath}`);
resolve(result.code);
} else {
resolve(bundledBuf);
}
}
});
});
}
/**
*
* @returns {Array}
* @private
*/
_generateIncludePaths() {
let _this = this,
compressPaths = [],
ignore = ['.DS_Store'],
stats,
fullPath;
_this._awsmJson.package.optimize.includePaths.forEach(p => {
try {
fullPath = path.resolve(path.join(_this._distDir, p));
stats = fs.lstatSync(fullPath);
} catch (e) {
console.error('Cant find includePath ', p, e);
throw e;
}
if (stats.isFile()) {
JawsUtils.jawsDebug('INCLUDING', fullPath);
compressPaths.push({fileName: p, data: fs.readFileSync(fullPath)});
} else if (stats.isDirectory()) {
let dirname = path.basename(p);
wrench
.readdirSyncRecursive(fullPath)
.forEach(file => {
// Ignore certain files
for (let i = 0; i < ignore.length; i++) {
if (file.toLowerCase().indexOf(ignore[i]) > -1) return;
}
let filePath = [fullPath, file].join('/');
if (fs.lstatSync(filePath).isFile()) {
let pathInZip = path.join(dirname, file);
JawsUtils.jawsDebug('INCLUDING', pathInZip);
compressPaths.push({fileName: pathInZip, data: fs.readFileSync(filePath)});
}
});
}
});
return compressPaths;
}
/**
*
* @param compressPaths
* @param targetZipPath string
* @returns {Promise.string} targetZipPath
* @private
*/
_compressCode(compressPaths, targetZipPath) {
let zip = new Zip();
compressPaths.forEach(nc => {
zip.file(nc.fileName, nc.data);
});
let zipBuffer = zip.generate({
type: 'nodebuffer',
compression: 'DEFLATE',
});
if (zipBuffer.length > 52428800) {
Promise.reject(new JawsError(
'Zip file is > the 50MB Lambda deploy limit (' + zipBuffer.length + ' bytes)',
JawsError.errorCodes.ZIP_TOO_BIG)
);
}
fs.writeFileSync(targetZipPath, zipBuffer);
JawsCLI.log(`Lambda Deployer: Compressed code written to ${targetZipPath}`);
return Promise.resolve(targetZipPath);
}
}
class DeployLambda extends JawsPlugin {
@ -570,6 +250,7 @@ class DeployLambda extends JawsPlugin {
*
* @returns {string}
*/
static getName() {
return 'jaws.core.' + DeployLambda.name;
}

View File

@ -17,8 +17,8 @@ let BbPromise = require('bluebird'),
// Promisify fs module. This adds "Async" to the end of every method
BbPromise.promisifyAll(fs);
module.exports = function(config) {
// Promisify and configure instance
const S3 = BbPromise.promisifyAll(new AWS.S3(config));
@ -48,6 +48,7 @@ module.exports = function(config) {
/**
* Get the env file for a given stage
*/
S3.sGetEnvFile = function(bucketName, projectName, stage) {
let key = ['JAWS', projectName, stage, 'envVars', '.env'].join('/'),
params = {
@ -56,7 +57,7 @@ module.exports = function(config) {
};
JawsUtils.jawsDebug(`env get s3 bucket: ${bucketName} key: ${key}`);
return S3.getObjectAsync(params);
return S3.getObjectAsync(params)
};
/**
@ -94,6 +95,7 @@ module.exports = function(config) {
return key;
});
};
// Return configured, customized instance
return S3;

View File

@ -47,14 +47,12 @@
"browserify": "^12.0.1",
"chalk": "^1.1.0",
"cli-spinner": "^0.2.1",
"commander": "^2.5.0",
"commop": "^1.2.0",
"debug": "^2.2.0",
"dotenv": "^1.2.0",
"download": "^4.2.0",
"expand-home-dir": "0.0.2",
"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",

View File

@ -18,7 +18,8 @@
"lambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "",
"Runtime": "nodejs",
"Handler": "aws_modules/bundle/browserify/handler.handler"
"Role": {
"Ref": "aaLambdaRoleArn"
},
@ -26,12 +27,9 @@
"S3Bucket": "",
"S3Key": ""
},
"Runtime": "nodejs",
"Timeout": 6,
"MemorySize": 1024
},
"Runtime": "nodejs",
"Handler": "aws_modules/bundle/browserify/handler.handler"
}
},
"apiGatewayEndpoint": {
"Type": "AWS::ApiGateway::Endpoint",

View File

@ -18,7 +18,8 @@
"lambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "",
"Runtime": "nodejs",
"Handler": "aws_modules/bundle/nonoptimized/handler.handler",
"Role": {
"Ref": "aaLambdaRoleArn"
},
@ -26,12 +27,9 @@
"S3Bucket": "",
"S3Key": ""
},
"Runtime": "nodejs",
"Timeout": 6,
"MemorySize": 1024
},
"Runtime": "nodejs",
"Handler": "aws_modules/bundle/nonoptimized/handler.handler"
}
},
"apiGatewayEndpoint": {
"Type": "AWS::ApiGateway::Endpoint",

View File

@ -18,7 +18,8 @@
"lambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "",
"Runtime": "nodejs",
"Handler": "aws_modules/sessions/create/index.handler",
"Role": {
"Ref": "aaLambdaRoleArn"
},
@ -26,12 +27,9 @@
"S3Bucket": "",
"S3Key": ""
},
"Runtime": "nodejs",
"Timeout": 6,
"MemorySize": 1024
},
"Runtime": "nodejs",
"Handler": "aws_modules/sessions/create/index.handler"
},
"apiGatewayEndpoint": {
"Type": "AWS::ApiGateway::Endpoint",

View File

@ -18,7 +18,8 @@
"lambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "",
"Runtime": "nodejs",
"Handler": "aws_modules/sessions/show/index.handler",
"Role": {
"Ref": "aaLambdaRoleArn"
},
@ -26,12 +27,9 @@
"S3Bucket": "",
"S3Key": ""
},
"Runtime": "nodejs",
"Timeout": 6,
"MemorySize": 1024
},
"Runtime": "nodejs",
"Handler": "aws_modules/sessions/show/index.handler"
}
},
"apiGateway": {
"Endpoint": {

View File

@ -19,7 +19,8 @@
"lambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Handler": "",
"Runtime": "nodejs",
"Handler": "aws_modules/users/create/index.handler",
"Role": {
"Ref": "aaLambdaRoleArn"
},
@ -27,12 +28,9 @@
"S3Bucket": "",
"S3Key": ""
},
"Runtime": "nodejs",
"Timeout": 6,
"MemorySize": 1024
},
"Runtime": "nodejs",
"Handler": "aws_modules/users/create/index.handler"
}
},
"apiGateway": {

View File

@ -13,16 +13,19 @@ let JAWS = require('../../../lib/Jaws.js'),
let Jaws;
describe('Test action: Function Deploy', function() {
describe('Test Action: Function Deploy', function() {
before(function(done) {
this.timeout(0);
testUtils.createTestProject(config)
.then(projPath => {
process.chdir(projPath);
Jaws = new JAWS({
interactive: false,
awsAdminKeyId: config.awsAdminKeyId,
awsAdminSecretKey: config.awsAdminSecretKey
});
done();
@ -33,16 +36,16 @@ describe('Test action: Function Deploy', function() {
done();
});
describe('Function Deploy Endpoint positive tests', function() {
describe('Function Deploy Code Lambda Nodejs', function() {
it('Function Deploy Code Lambda Nodejs', function(done) {
it('Function Deploy Endpoint', function(done) {
this.timeout(0);
let event = {
stage: config.stage,
region: config.region,
noExeCf: config.noExecuteCf,
type: 'endpoint',
type: 'code',
functions: ['aws_modules/users/create'],
};
@ -55,4 +58,27 @@ describe('Test action: Function Deploy', function() {
});
});
});
//describe('Function Deploy: Endpoint: ApiGateway', function() {
//
// it('Function Deploy Endpoint', function(done) {
// this.timeout(0);
//
// let event = {
// stage: config.stage,
// region: config.region,
// noExeCf: config.noExecuteCf,
// type: 'endpoint',
// functions: ['aws_modules/users/create'],
// };
//
// Jaws.actions.functionDeploy(event)
// .then(function() {
// done();
// })
// .catch(e => {
// done(e);
// });
// });
//});
});