From a6d5650ac980981ec4858e628a1e84b32fc2b273 Mon Sep 17 00:00:00 2001 From: Chase Sillevis Date: Fri, 2 Sep 2016 09:37:50 +0200 Subject: [PATCH] Support AWS_PROFILE from @EduardoMartinezCatala, add a few linting suggestions --- README.md | 13 ++++---- bin/node-lambda | 20 +++++++------ lib/.env.example | 1 + lib/main.js | 78 +++++++++++++++++++++++++----------------------- 4 files changed, 61 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index c898425f..02c44c9b 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ $ node-lambda run --help Options: -h, --help Output usage information - --handler [index.handler] Lambda Handler {index.handler} + -H, --handler [index.handler] Lambda Handler {index.handler} -j, --eventFile [event.json] Event JSON File -f, --configFile [] Path to file holding secret environment variables (e.g. "deploy.env") -u, --runtime [nodejs4.3] Lambda Runtime {nodejs4.3, nodejs} - "nodejs4.3" is the current standard, "nodejs" is v0.10.36 @@ -85,12 +85,13 @@ $ node-lambda package --help Options: -h, --help output usage information - -p, --packageDirectory [build] Local Package Directory + -A, --packageDirectory [build] Local Package Directory -n, --functionName [node-lambda] Lambda FunctionName + -H, --handler [index.handler] Lambda Handler {index.handler} -e, --environment [staging] Choose environment {development, staging, production} -f, --configFile [] Path to file holding secret environment variables (e.g. "deploy.env") -x, --excludeGlobs [] Add a space separated list of file(type)s to ignore (e.g. "*.json .env") - -P, --prebuiltDirectory [] Prebuilt directory + -D, --prebuiltDirectory [] Prebuilt directory ``` @@ -109,10 +110,11 @@ $ node-lambda deploy --help -e, --environment [staging] Choose environment {development, staging, production} -a, --accessKey [your_key] AWS Access Key -s, --secretKey [your_secret] AWS Secret Key + -P, --profile [your_profile] AWS Profile -k, --sessionToken [your_token] AWS Session Token -r, --region [us-east-1] AWS Region(s) -n, --functionName [node-lambda] Lambda FunctionName - --handler [index.handler] Lambda Handler {index.handler} + -H, --handler [index.handler] Lambda Handler {index.handler} -o, --role [your_role] Amazon Role ARN -m, --memorySize [128] Lambda Memory Size -t, --timeout [3] Lambda Timeout @@ -123,8 +125,9 @@ $ node-lambda deploy --help -f, --configFile [] Path to file holding secret environment variables (e.g. "deploy.env") -b, --vpcSubnets [] VPC Subnet ID(s, comma separated list) for your Lambda Function, when using this, the below param is also required -g, --vpcSecurityGroups [] VPC Security Group ID(s, comma separated list) for your Lambda Function, when using this, the above param is also required + -A, --packageDirectory [] Local package directory -x, --excludeGlobs [] Add a space separated list of file(type)s to ignore (e.g. "*.json .env") - -P, --prebuiltDirectory [] Prebuilt directory + -D, --prebuiltDirectory [] Prebuilt directory ``` ## Custom Environment Variables diff --git a/bin/node-lambda b/bin/node-lambda index ae68e04a..71338bb9 100755 --- a/bin/node-lambda +++ b/bin/node-lambda @@ -4,8 +4,8 @@ var dotenv = require('dotenv'); var lambda = require('../lib/main.js'); var program = require('commander'); var fs = require('fs'); -var packageJson = fs.existsSync(process.cwd() + '/package.json') - ? require(process.cwd() + '/package.json') : {}; +var packageJson = fs.existsSync(process.cwd() + '/package.json') ? + require(process.cwd() + '/package.json') : {}; var packageJsonName = packageJson.name || 'UnnamedFunction'; dotenv.load(); @@ -15,6 +15,7 @@ var CONFIG_FILE = process.env.CONFIG_FILE || ''; var EXCLUDE_GLOBS = process.env.EXCLUDE_GLOBS || ''; var AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID; var AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY; +var AWS_PROFILE = process.env.AWS_PROFILE || ''; var AWS_SESSION_TOKEN = process.env.AWS_SESSION_TOKEN || ''; var AWS_REGION = process.env.AWS_REGION || 'us-east-1,us-west-2,eu-west-1'; var AWS_FUNCTION_NAME = process.env.AWS_FUNCTION_NAME || packageJsonName; @@ -43,10 +44,11 @@ program AWS_ENVIRONMENT) .option('-a, --accessKey [' + AWS_ACCESS_KEY_ID + ']', 'AWS Access Key', AWS_ACCESS_KEY_ID) .option('-s, --secretKey [' + AWS_SECRET_ACCESS_KEY + ']', 'AWS Secret Key', AWS_SECRET_ACCESS_KEY) + .option('-P, --profile [' + AWS_PROFILE + ']', 'AWS Profile', AWS_PROFILE) .option('-k, --sessionToken [' + AWS_SESSION_TOKEN + ']', 'AWS Session Token', AWS_SESSION_TOKEN) .option('-r, --region [' + AWS_REGION + ']', 'AWS Region', AWS_REGION) .option('-n, --functionName [' + AWS_FUNCTION_NAME + ']', 'Lambda FunctionName', AWS_FUNCTION_NAME) - .option('--handler [' + AWS_HANDLER + ']', 'Lambda Handler {index.handler}', AWS_HANDLER) + .option('-H, --handler [' + AWS_HANDLER + ']', 'Lambda Handler {index.handler}', AWS_HANDLER) .option('-o, --role [' + AWS_ROLE + ']', 'Amazon Role ARN', AWS_ROLE) .option('-m, --memorySize [' + AWS_MEMORY_SIZE + ']', 'Lambda Memory Size', AWS_MEMORY_SIZE) .option('-t, --timeout [' + AWS_TIMEOUT + ']', 'Lambda Timeout', AWS_TIMEOUT) @@ -57,12 +59,12 @@ program .option('-b, --vpcSubnets [' + AWS_VPC_SUBNETS + ']', 'Lambda Function VPC Subnets', AWS_VPC_SUBNETS) .option('-g, --vpcSecurityGroups [' + AWS_VPC_SECURITY_GROUPS + ']', 'Lambda VPC Security Group', AWS_VPC_SECURITY_GROUPS) - .option('-p, --packageDirectory [' + PACKAGE_DIRECTORY + ']', 'Local Package Directory', PACKAGE_DIRECTORY) + .option('-A, --packageDirectory [' + PACKAGE_DIRECTORY + ']', 'Local Package Directory', PACKAGE_DIRECTORY) .option('-f, --configFile [' + CONFIG_FILE + ']', 'Path to file holding secret environment variables (e.g. "deploy.env")', CONFIG_FILE) .option('-x, --excludeGlobs [' + EXCLUDE_GLOBS + ']', 'Space-separated glob pattern(s) for additional exclude files (e.g. "event.json dotenv.sample")', EXCLUDE_GLOBS) - .option('-P, --prebuiltDirectory [' + PREBUILT_DIRECTORY + ']', 'Prebuilt directory', PREBUILT_DIRECTORY) + .option('-D, --prebuiltDirectory [' + PREBUILT_DIRECTORY + ']', 'Prebuilt directory', PREBUILT_DIRECTORY) .action(function (prg) { lambda.deploy(prg); }); @@ -71,16 +73,16 @@ program .version(lambda.version) .command('package') .description('Create zipped package for Amazon Lambda deployment') - .option('-p, --packageDirectory [' + PACKAGE_DIRECTORY + ']', 'Local Package Directory', PACKAGE_DIRECTORY) + .option('-A, --packageDirectory [' + PACKAGE_DIRECTORY + ']', 'Local Package Directory', PACKAGE_DIRECTORY) .option('-n, --functionName [' + AWS_FUNCTION_NAME + ']', 'Lambda FunctionName', AWS_FUNCTION_NAME) - .option('--handler [' + AWS_HANDLER + ']', 'Lambda Handler {index.handler}', AWS_HANDLER) + .option('-H, --handler [' + AWS_HANDLER + ']', 'Lambda Handler {index.handler}', AWS_HANDLER) .option('-e, --environment [' + AWS_ENVIRONMENT + ']', 'Choose environment {dev, staging, production}', AWS_ENVIRONMENT) .option('-x, --excludeGlobs [' + EXCLUDE_GLOBS + ']', 'Space-separated glob pattern(s) for additional exclude files (e.g. "event.json dotenv.sample")', EXCLUDE_GLOBS) .option('-f, --configFile [' + CONFIG_FILE + ']', 'Path to file holding secret environment variables (e.g. "deploy.env")', CONFIG_FILE) - .option('-P, --prebuiltDirectory [' + PREBUILT_DIRECTORY + ']', 'Prebuilt directory', PREBUILT_DIRECTORY) + .option('-D, --prebuiltDirectory [' + PREBUILT_DIRECTORY + ']', 'Prebuilt directory', PREBUILT_DIRECTORY) .action(function (prg) { lambda.package(prg); }); @@ -89,7 +91,7 @@ program .version(lambda.version) .command('run') .description('Run your Amazon Lambda application locally') - .option('--handler [' + AWS_HANDLER + ']', 'Lambda Handler {index.handler}', AWS_HANDLER) + .option('-H, --handler [' + AWS_HANDLER + ']', 'Lambda Handler {index.handler}', AWS_HANDLER) .option('-j, --eventFile [' + EVENT_FILE + ']', 'Event JSON File', EVENT_FILE) .option('-u, --runtime [' + AWS_RUNTIME + ']', 'Lambda Runtime', AWS_RUNTIME) .option('-f, --configFile [' + CONFIG_FILE + ']', diff --git a/lib/.env.example b/lib/.env.example index 1fd0bcd2..dc9ed6c1 100644 --- a/lib/.env.example +++ b/lib/.env.example @@ -1,6 +1,7 @@ AWS_ENVIRONMENT=development AWS_ACCESS_KEY_ID=your_key AWS_SECRET_ACCESS_KEY=your_secret +AWS_PROFILE= AWS_SESSION_TOKEN= AWS_ROLE_ARN=your_amazon_role AWS_REGION=us-east-1 diff --git a/lib/main.js b/lib/main.js index 010b7f88..5834d41b 100644 --- a/lib/main.js +++ b/lib/main.js @@ -33,7 +33,8 @@ Lambda.prototype.setup = function (program) { this._createSampleFile(program.eventFile, 'event.json'); this._createSampleFile('deploy.env', 'deploy.env'); this._createSampleFile(program.contextFile, 'context.json'); - console.log('Setup done. Edit the .env, deploy.env, ' + program.contextFile + ' and ' + program.eventFile + ' files as needed.'); + console.log('Setup done. Edit the .env, deploy.env, ' + program.contextFile + ' and ' + program.eventFile + + ' files as needed.'); }; Lambda.prototype.run = function (program) { @@ -60,8 +61,7 @@ Lambda.prototype._runHandler = function (handler, event, runtime, context) { if (err) { console.log('Error: ' + err); process.exit(-1); - } - else { + } else { console.log('Success:'); if (result) { console.log(JSON.stringify(result)); @@ -93,10 +93,10 @@ Lambda.prototype._runHandler = function (handler, event, runtime, context) { switch(runtime) { case "nodejs": handler(event, context); - break; + break; case "nodejs4.3": handler(event, context, callback); - break; + break; default: console.error("Runtime [" + runtime + "] is not supported."); } @@ -151,11 +151,11 @@ Lambda.prototype._rsync = function (program, src, dest, excludeNodeModules, call var excludeArgs = excludeGlobs .concat(excludes) .concat(excludeNodeModules ? ['node_modules'] : []) - .map(function(exclude) { + .map(function (exclude) { return '--exclude=' + exclude; }).join(' '); - exec('mkdir -p ' + dest, function(err) { + exec('mkdir -p ' + dest, function (err) { if (err) { return callback(err); } @@ -184,23 +184,21 @@ Lambda.prototype._npmInstall = function (program, codeDirectory, callback) { Lambda.prototype._postInstallScript = function (codeDirectory, callback) { var script_filename = 'post_install.sh'; - var cmd = './'+script_filename; + var cmd = './' + script_filename; var filePath = [codeDirectory, script_filename].join('/'); - fs.exists(filePath, function(exists) { + fs.exists(filePath, function (exists) { if (exists) { console.log('=> Running post install script '+script_filename); - exec(cmd, { cwd: codeDirectory,maxBuffer: 50 * 1024 * 1024 }, function(error, stdout, stderr){ - - if (error) callback(error +" stdout: " + stdout + "stderr"+stderr); - else { - console.log("\t\t"+stdout); + exec(cmd, { cwd: codeDirectory,maxBuffer: 50 * 1024 * 1024 }, function (error, stdout, stderr) { + if (error) { + callback(error + " stdout: " + stdout + "stderr" + stderr); + } else { + console.log("\t\t" + stdout); callback(null); } }); - - } else { callback(null); } @@ -260,7 +258,7 @@ Lambda.prototype._cleanDirectory = function (codeDirectory, callback) { throw err; } - fs.mkdir(codeDirectory, function(err) { + fs.mkdir(codeDirectory, function (err) { if (err) { throw err; } @@ -281,7 +279,7 @@ Lambda.prototype._setEnvironmentVars = function (program, codeDirectory) { var config = dotenv.parse(configValues); var contentStr = contents.toString(); - if(program.environment){ + if(program.environment) { prefix += 'process.env["environment"]=' + JSON.stringify(program.environment) + ';\n'; } @@ -314,16 +312,16 @@ Lambda.prototype._setRunTimeEnvironmentVars = function (program) { continue; } - process.env[k]=config[k]; + process.env[k] = config[k]; } }; -Lambda.prototype._uploadExisting = function(lambda, params, cb) { +Lambda.prototype._uploadExisting = function (lambda, params, cb) { return lambda.updateFunctionCode({ 'FunctionName': params.FunctionName, 'ZipFile': params.Code.ZipFile, 'Publish': params.Publish - }, function(err, data) { + }, function (err, data) { if(err) { return cb(err, data); } @@ -336,27 +334,26 @@ Lambda.prototype._uploadExisting = function(lambda, params, cb) { 'Role': params.Role, 'Timeout': params.Timeout, 'VpcConfig': params.VpcConfig - }, function(err, data) { + }, function (err, data) { return cb(err, data); }); }); }; -Lambda.prototype._uploadNew = function(lambda, params, cb) { - return lambda.createFunction(params, function(err, data) { +Lambda.prototype._uploadNew = function (lambda, params, cb) { + return lambda.createFunction(params, function (err, data) { return cb(err, data); }); }; Lambda.prototype._archive = function (program, archive_callback) { - return program.prebuiltDirectory - ? this._archivePrebuilt(program, archive_callback) - : this._buildAndArchive(program, archive_callback); -} + return program.prebuiltDirectory ? + this._archivePrebuilt(program, archive_callback) : + this._buildAndArchive(program, archive_callback); +}; Lambda.prototype._archivePrebuilt = function (program, archive_callback) { - - var codeDirectory = this._codeDirectory(program) + var codeDirectory = this._codeDirectory(program); var _this = this; this._rsync(program, program.prebuiltDirectory, codeDirectory, false, function (err) { if (err) { @@ -373,7 +370,7 @@ Lambda.prototype._archivePrebuilt = function (program, archive_callback) { archive(program, codeDirectory, archive_callback); }); -} +}; Lambda.prototype._buildAndArchive = function (program, archive_callback) { this._createSampleFile('.env', '.env'); @@ -389,7 +386,7 @@ Lambda.prototype._buildAndArchive = function (program, archive_callback) { var _this = this; var codeDirectory = _this._codeDirectory(program); - _this._cleanDirectory(codeDirectory, function(err) { + _this._cleanDirectory(codeDirectory, function (err) { if (err) { return archive_callback(err); } @@ -455,7 +452,7 @@ Lambda.prototype.package = function (program) { var basename = program.functionName + (program.environment ? '-' + program.environment : ''); var zipfile = path.join(program.packageDirectory, basename + '.zip'); console.log('=> Writing packaged zip'); - fs.writeFile(zipfile, buffer, function(err) { + fs.writeFile(zipfile, buffer, function (err) { if (err) { throw err; } @@ -480,12 +477,19 @@ Lambda.prototype.deploy = function (program) { console.log(params); var aws_security = { - accessKeyId: program.accessKey, - secretAccessKey: program.secretKey, region: region }; - if (program.sessionToken){ + if (program.profile) { + aws.config.credentials = new aws.SharedIniFileCredentials({ + profile: program.profile + }); + } else { + aws_security.accessKeyId = program.accessKey; + aws_security.secretAccessKey = program.secretKey; + } + + if (program.sessionToken) { aws_security.sessionToken = program.sessionToken; } @@ -497,7 +501,7 @@ Lambda.prototype.deploy = function (program) { return lambda.getFunction({ 'FunctionName': params.FunctionName - }, function(err) { + }, function (err) { if(err) { return _this._uploadNew(lambda, params, cb); }