From ec17ebd758059befeb40d2ddbcdac0c87a0b86be Mon Sep 17 00:00:00 2001 From: ac360 Date: Fri, 1 Jan 2016 15:43:41 -0800 Subject: [PATCH] merge --- lib/actions/CodeDeployLambdaNodeJs.js | 320 +++++++++++++------------ lib/actions/CodePackageLambdaNodeJs.js | 135 ++++++----- 2 files changed, 234 insertions(+), 221 deletions(-) diff --git a/lib/actions/CodeDeployLambdaNodeJs.js b/lib/actions/CodeDeployLambdaNodeJs.js index dbd9d1ea2..6f11bad36 100644 --- a/lib/actions/CodeDeployLambdaNodeJs.js +++ b/lib/actions/CodeDeployLambdaNodeJs.js @@ -7,7 +7,7 @@ * - WARNING: This Action runs concurrently. */ -module.exports = function(SPlugin, serverlessPath) { +module.exports = function(SPlugin, serverlessPath) { const path = require('path'), SError = require(path.join(serverlessPath, 'ServerlessError')), SUtils = require(path.join(serverlessPath, 'utils/index')), @@ -43,14 +43,14 @@ module.exports = function(SPlugin, serverlessPath) { * Deploy Code Lambda Node.Js */ - codeDeployLambdaNodejs(evt) { + codeDeployLambdaNodejs(options) { let deployer = new Deployer(this.S); - return deployer.deploy(evt); + return deployer.deploy(options); } } /** - * Deployer + * Deployer Class * - Necessary for this action to run concurrently */ @@ -60,73 +60,79 @@ module.exports = function(SPlugin, serverlessPath) { this.S = S; } - deploy(evt) { + deploy(options) { + let _this = this; + _this.options = options; // Load AWS Service Instances let awsConfig = { - region: evt.region.region, + region: this.options.region, accessKeyId: _this.S.config.awsAdminKeyId, - secretAccessKey: _this.S.config.awsAdminSecretKey, + secretAccessKey: _this.S.config.awsAdminSecretKey }; - _this.S3 = require('../utils/aws/S3')(awsConfig); - _this.Lambda = require('../utils/aws/Lambda')(awsConfig); - _this.AwsMisc = require('../utils/aws/Misc'); + _this.S3 = require('../utils/aws/S3')(awsConfig); + _this.Lambda = require('../utils/aws/Lambda')(awsConfig); + _this.AwsMisc = require('../utils/aws/Misc'); + + // Instantiate Classes + _this.project = _this.S.classes.Project(_this.S); + _this.meta = _this.S.classes.Meta(_this.S); // Flow - return _this._validateAndPrepare(evt) - .bind(_this) - .then(_this._compress) - .then(_this._upload) - .then(_this._deploy) - .then(function() { - return evt; - }); + return _this._validateAndPrepare() + .bind(_this) + .then(_this._compress) + .then(_this._upload) + .then(_this._deploy) + .then(function() { + return options; + }); } /** * Validate And Prepare */ - _validateAndPrepare(evt) { - return BbPromise.resolve(evt); + _validateAndPrepare() { + return BbPromise.resolve(); } /** * Compress */ - _compress(evt) { + _compress() { let zip = new Zip(); - evt.function.pathsPackaged.forEach(nc => { + this.options.function.pathsPackaged.forEach(nc => { zip.file(nc.fileName, nc.data); }); let zipBuffer = zip.generate({ type: 'nodebuffer', - compression: 'DEFLATE', + compression: 'DEFLATE' }); if (zipBuffer.length > 52428800) { Promise.reject(new SError( - 'Zip file is > the 50MB Lambda queued limit (' + zipBuffer.length + ' bytes)', - SError.errorCodes.ZIP_TOO_BIG) + 'Zip file is > the 50MB Lambda queued limit (' + zipBuffer.length + ' bytes)', + SError.errorCodes.ZIP_TOO_BIG) ); } // Set path of compressed package - evt.function.pathCompressed = path.join(evt.function.pathDist, 'package.zip'); + this.pathCompressed = path.join(this.options.pathDist, 'package.zip'); // Create compressed package fs.writeFileSync( - evt.function.pathCompressed, - zipBuffer); + this.pathCompressed, + zipBuffer); - SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Compressed file created - ${evt.function.pathCompressed}`); + SUtils.sDebug(`"${this.options.stage} - ${this.options.region.region} - ${this.function.data.name}": Compressed file created - ${this.pathCompressed}`); - return BbPromise.resolve(evt); + return BbPromise.resolve(); } /** @@ -138,22 +144,22 @@ module.exports = function(SPlugin, serverlessPath) { let _this = this; - SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Uploading to - ${evt.region.regionBucket}`); + SUtils.sDebug(`"${this.options.stage} - ${this.options.region} - ${this.function.data.name}": Uploading to project bucket...`); return _this.S3.sPutLambdaZip( - evt.region.regionBucket, - _this.S.data.project.get('name'), - evt.stage, - evt.function.name, - fs.createReadStream(evt.function.pathCompressed)) - .then(function(s3Key) { + this.projectBucket, + _this.S.data.project.get('name'), + this.options.stage, + this.function.name, + fs.createReadStream(this.pathCompressed)) + .then(function(s3Key) { - // Store S3 Data - evt.function.s3Bucket = evt.region.regionBucket; - evt.function.s3Key = s3Key; + // Store S3 Data + this.function.s3Bucket = this.region.regionBucket; + this.function.s3Key = s3Key; - return BbPromise.resolve(evt); - }); + return BbPromise.resolve(); + }); } /** @@ -161,11 +167,11 @@ module.exports = function(SPlugin, serverlessPath) { * - Deploy Lambda from S3 to Lambda */ - _deploy(evt) { + _deploy() { let _this = this, - lambda, - lambdaVersion; + lambda, + lambdaVersion; var params = { FunctionName: _this.Lambda.sGetLambdaName(_this.S.data.project.get('name'), evt.function.name), @@ -173,141 +179,141 @@ module.exports = function(SPlugin, serverlessPath) { }; return _this.Lambda.getFunctionPromised(params) - .catch(function(e) { - lambda = null; - }) - .then(function(data) { - lambda = data; - }) - .then(function() { + .catch(function(e) { + lambda = null; + }) + .then(function(data) { + lambda = data; + }) + .then(function() { - // Create or Update Lambda + // Create or Update Lambda - if (!lambda) { + if (!lambda) { - SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Creating Lambda function...`); + SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Creating Lambda function...`); - // Create Lambda - let params = { - Code: { - S3Bucket: evt.function.s3Bucket, - S3Key: evt.function.s3Key - }, - FunctionName: _this.Lambda.sGetLambdaName(_this.S.data.project.get('name'), evt.function.name), /* required */ - Handler: evt.function.handler, /* required */ - Role: evt.region.iamRoleArnLambda, /* required */ - Runtime: evt.function.module.runtime, /* required */ - Description: 'Serverless Lambda function for project: ' + _this.S.data.project.get('name'), - MemorySize: evt.function.memorySize, - Publish: true, // Required by Serverless Framework & recommended by AWS - Timeout: evt.function.timeout - }; - return _this.Lambda.createFunctionPromised(params) + // Create Lambda + let params = { + Code: { + S3Bucket: evt.function.s3Bucket, + S3Key: evt.function.s3Key + }, + FunctionName: _this.Lambda.sGetLambdaName(_this.S.data.project.get('name'), evt.function.name), /* required */ + Handler: evt.function.handler, /* required */ + Role: evt.region.iamRoleArnLambda, /* required */ + Runtime: evt.function.module.runtime, /* required */ + Description: 'Serverless Lambda function for project: ' + _this.S.data.project.get('name'), + MemorySize: evt.function.memorySize, + Publish: true, // Required by Serverless Framework & recommended by AWS + Timeout: evt.function.timeout + }; + return _this.Lambda.createFunctionPromised(params) + .then(function(data) { + + // Save Version + lambdaVersion = data.Version; + + return data; + }) + .catch(function(e){ + console.log(e) + }) + + } else { + + SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Updating Lambda configuration...`); + + let params = { + FunctionName: lambda.Configuration.FunctionName, /* required */ + Description: 'Serverless Lambda function for project: ' + _this.S._project.name, + Handler: evt.function.handler, + MemorySize: evt.function.memorySize, + Role: evt.region.iamRoleArnLambda, + Timeout: evt.function.timeout + }; + + return _this.Lambda.updateFunctionConfigurationPromised(params) + .then(function(){ + SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Updating Lambda function...`); + + // Update Lambda Code + let params = { + FunctionName: lambda.Configuration.FunctionName, /* required */ + Publish: true, // Required by Serverless Framework & recommended by AWS + S3Bucket: evt.region.regionBucket, + S3Key: evt.function.s3Key, + }; + return _this.Lambda.updateFunctionCodePromised(params) .then(function(data) { // Save Version lambdaVersion = data.Version; - return data; - }) - .catch(function(e){ - console.log(e) - }) + return( data ); + }); + }); + } + }) + .then(function(data) { - } else { + // Alias Lambda w/ Stage - SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Updating Lambda configuration...`); + let aliasedLambda = false; - let params = { - FunctionName: lambda.Configuration.FunctionName, /* required */ - Description: 'Serverless Lambda function for project: ' + _this.S._project.name, - Handler: evt.function.handler, - MemorySize: evt.function.memorySize, - Role: evt.region.iamRoleArnLambda, - Timeout: evt.function.timeout - }; + var params = { + FunctionName: data.FunctionName, /* required */ + Name: evt.stage.toLowerCase() /* required */ + }; - return _this.Lambda.updateFunctionConfigurationPromised(params) - .then(function(){ - SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Updating Lambda function...`); + return _this.Lambda.getAliasPromised(params) + .then(function() { + aliasedLambda = true; + }) + .catch(function(e) { + aliasedLambda = false; + }) + .then(function() { - // Update Lambda Code - let params = { - FunctionName: lambda.Configuration.FunctionName, /* required */ - Publish: true, // Required by Serverless Framework & recommended by AWS - S3Bucket: evt.region.regionBucket, - S3Key: evt.function.s3Key, - }; - return _this.Lambda.updateFunctionCodePromised(params) - .then(function(data) { + if (aliasedLambda) { - // Save Version - lambdaVersion = data.Version; + // Update Existing Alias - return( data ); - }); - }); - } - }) - .then(function(data) { + SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Updating Lambda Alias for version - ${lambdaVersion}`); - // Alias Lambda w/ Stage + let params = { + FunctionName: data.FunctionName, /* required */ + FunctionVersion: lambdaVersion, /* required */ + Name: evt.stage, /* required */ + Description: 'Project: ' + _this.S._project.name + ' Stage: ' + evt.stage + }; - let aliasedLambda = false; + return _this.Lambda.updateAliasPromised(params); - var params = { - FunctionName: data.FunctionName, /* required */ - Name: evt.stage.toLowerCase() /* required */ - }; + } else { - return _this.Lambda.getAliasPromised(params) - .then(function() { - aliasedLambda = true; - }) - .catch(function(e) { - aliasedLambda = false; - }) - .then(function() { + // Create New Alias - if (aliasedLambda) { + SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Creating New Lambda Alias for version - ${lambdaVersion}`); - // Update Existing Alias + let params = { + FunctionName: data.FunctionName, /* required */ + FunctionVersion: lambdaVersion, /* required */ + Name: evt.stage, /* required */ + Description: 'Project: ' + _this.S._project.name + ' Stage: ' + evt.stage + }; - SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Updating Lambda Alias for version - ${lambdaVersion}`); - - let params = { - FunctionName: data.FunctionName, /* required */ - FunctionVersion: lambdaVersion, /* required */ - Name: evt.stage, /* required */ - Description: 'Project: ' + _this.S._project.name + ' Stage: ' + evt.stage - }; - - return _this.Lambda.updateAliasPromised(params); - - } else { - - // Create New Alias - - SUtils.sDebug(`"${evt.stage} - ${evt.region.region} - ${evt.function.name}": Creating New Lambda Alias for version - ${lambdaVersion}`); - - let params = { - FunctionName: data.FunctionName, /* required */ - FunctionVersion: lambdaVersion, /* required */ - Name: evt.stage, /* required */ - Description: 'Project: ' + _this.S._project.name + ' Stage: ' + evt.stage - }; - - return _this.Lambda.createAliasPromised(params); - } - }) - .then(function(data) { - // Add Version & Alias information to evt - evt.function.deployedVersion = data.FunctionVersion; - evt.function.deployedAlias = evt.stage; - evt.function.deployedAliasArn = data.AliasArn; - return evt - }); - }) + return _this.Lambda.createAliasPromised(params); + } + }) + .then(function(data) { + // Add Version & Alias information to evt + evt.function.deployedVersion = data.FunctionVersion; + evt.function.deployedAlias = evt.stage; + evt.function.deployedAliasArn = data.AliasArn; + return evt + }); + }) } } diff --git a/lib/actions/CodePackageLambdaNodeJs.js b/lib/actions/CodePackageLambdaNodeJs.js index e41bfb020..fbd1b1592 100644 --- a/lib/actions/CodePackageLambdaNodeJs.js +++ b/lib/actions/CodePackageLambdaNodeJs.js @@ -11,12 +11,12 @@ module.exports = function(SPlugin, serverlessPath) { const path = require('path'), - SError = require(path.join(serverlessPath, 'ServerlessError')), - SUtils = require(path.join(serverlessPath, 'utils/index')), - BbPromise = require('bluebird'), - fs = require('fs'), - os = require('os'), - wrench = require('wrench'); + SError = require(path.join(serverlessPath, 'ServerlessError')), + SUtils = require(path.join(serverlessPath, 'utils/index')), + BbPromise = require('bluebird'), + fs = require('fs'), + os = require('os'), + wrench = require('wrench'); // Promisify fs module BbPromise.promisifyAll(fs); @@ -81,12 +81,12 @@ module.exports = function(SPlugin, serverlessPath) { // Flow return _this._validateAndPrepare() - .bind(_this) - .then(_this._createDistFolder) - .then(_this._package) - .then(function() { - return options; - }); + .bind(_this) + .then(_this._createDistFolder) + .then(_this._package) + .then(function() { + return options; + }); } /** @@ -136,48 +136,48 @@ module.exports = function(SPlugin, serverlessPath) { let excludePatterns = this.function.data.custom.excludePatterns || []; wrench.copyDirSyncRecursive( - path.join(_this.S.config.projectPath, 'back'), + path.join(_this.S.config.projectPath, 'back'), _this.pathDist, - { - exclude: function(name, prefix) { + { + exclude: function(name, prefix) { - if (!excludePatterns.length) { - return false; + if (!excludePatterns.length) { + return false; + } + + let relPath = path.join( + prefix.replace(_this.pathDist, ''), 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) { + SUtils.sDebug(`"${_this.options.stage} - ${_this.options.region} - ${_this.function.data.name}": Excluding - ${relPath}`); } - let relPath = path.join( - prefix.replace(_this.pathDist, ''), 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) { - SUtils.sDebug(`"${_this.options.stage} - ${_this.options.region} - ${_this.function.data.name}": Excluding - ${relPath}`); - } - - return willExclude; - }); - } + return willExclude; + }); } + } ); // Get ENV file from S3 return _this.S3.sGetEnvFile( - this.regionBucket, - _this.project.data.name, - this.options.stage, - this.options.region) - .then(function(s3ObjData) { + this.regionBucket, + _this.project.data.name, + this.options.stage, + this.options.region) + .then(function(s3ObjData) { - fs.writeFileSync( - path.join(this.pathDist,'.env'), - s3ObjData.Body); + fs.writeFileSync( + path.join(this.pathDist,'.env'), + s3ObjData.Body); - }); + }); } /** @@ -190,23 +190,23 @@ module.exports = function(SPlugin, serverlessPath) { this.function.data.custom.includePaths = ['.']; // Create pathsPackaged for each file ready to compress - this.pathsPackaged = _this._generateIncludePaths(evt); + this.pathsPackaged = _this._generateIncludePaths(); - return BbPromise.resolve(evt); + return BbPromise.resolve(); } /** * Generate Include Paths */ - _generateIncludePaths(evt) { + _generateIncludePaths() { let compressPaths = [], - ignore = ['.DS_Store'], - stats, - fullPath; + ignore = ['.DS_Store'], + stats, + fullPath; - this.function.data.custom.includePaths.forEach(p => { + this.function.data.custom.includePaths.forEach(p => { try { fullPath = path.resolve(path.join(this.pathDist, p)); @@ -217,29 +217,36 @@ module.exports = function(SPlugin, serverlessPath) { } if (stats.isFile()) { - compressPaths.push({fileName: p, data: fs.readFileSync(fullPath)}); + + compressPaths.push({ + fileName: p, + data: fs.readFileSync(fullPath) + }); + } else if (stats.isDirectory()) { let dirname = path.basename(p); wrench - .readdirSyncRecursive(fullPath) - .forEach(file => { + .readdirSyncRecursive(fullPath) + .forEach(file => { - // Ignore certain files - for (let i = 0; i < ignore.length; i++) { - if (file.toLowerCase().indexOf(ignore[i]) > -1) return; - } + // 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); - compressPaths.push({fileName: pathInZip, data: fs.readFileSync(filePath)}); - } - }); + let filePath = [fullPath, file].join('/'); + if (fs.lstatSync(filePath).isFile()) { + let pathInZip = path.join(dirname, file); + compressPaths.push({ + fileName: pathInZip, + data: fs.readFileSync(filePath) + }); + } + }); } }); - return compressPaths; } }