#!/usr/bin/env node 'use strict'; var JawsError = require('../lib/jaws-error'), Jaws = require('../lib/index.js'), program = require('commander'), utils = require('../lib/utils'), Promise = require('bluebird'), rawDebug = require('debug'), execute = utils.execute; Promise.onPossiblyUnhandledRejection(function(error) { throw error; }); var JAWS = new Jaws(); program .option('-v, --verbose') .version(JAWS._meta.version); /** * New * - Create a new project|stage|region */ program .command('new [params]') .description('new project, stage and region commands\n\nValid \'s:' + '\n\nproject: create new JAWS project in CWD.' + '\n\t Ex: jaws new project' + '\n\nstage: create new stage in existing region' + '\n\t Ex: jaws new stage dev' + '\n\nregion: create new region for given stage' + '\n\t Ex: jaws new region dev' ) .option('-d, --dont-exe-cf', 'Don\'t execute CloudFormation, just generate it.') .option('-r, --region ', 'name of aws region to use') .option('-b, --s3-bucket ', '[project,region] only: JAWS S3 bucket name. Will be created if DNE in "project" cmd. Must exist for "region" cmd.') .option('-n, --proj-name ', '[project] only: name for new project') .option('-s, --stage ', '[project] only: same of stage for new project') .option('-e, --email ', '[project] only: notification email to use in CloudFormation') .option('-p, --aws-profile ', '[project] only: Admin AWS profile as defined in ~/.aws/credentials to use') .action(function(cmd, params, options) { if (cmd == 'project') { var CmdNewProject = require('../lib/commands/new_project'); execute(CmdNewProject.run( options.projName, options.stage ? options.stage.toLowerCase() : null, options.s3Bucket, options.region, options.email, options.awsProfile, options.dontExeCf )); } else if (cmd == 'region' || cmd == 'stage') { var theParams = process.argv.slice(3); if (!theParams) { throw new JawsError('Missing params', JawsError.errorCodes.UNKNOWN); } if (theParams[0][0] == '-') { //TODO: how do we get around this commander shortcoming? throw new JawsError('Specify options after cmd', JawsError.errorCodes.UNKNOWN); } //TODO: iterate thru cmds to see how many are before - if (theParams.length < 2) { throw new JawsError('must specify stage name', JawsError.errorCodes.UNKNOWN); } var CmdNewStageRegion = require('../lib/commands/new_stage_region'), stageName = theParams[1]; execute(CmdNewStageRegion.run( JAWS, cmd, stageName, options.region, options.s3Bucket, options.dontExeCf )); } else { console.error('Unsupported cmd ' + cmd + '. Must be project|stage|region'); process.exit(1); } }); program .command('run') .description('Run the lambda in CWD locally') .action(function() { var runner = require('../lib/commands/run'); execute(runner.run(JAWS)); }); program .command('module [params]') .description('aws-module commands\n\nValid \'s:' + '\n\ninstall: install aws-module.' + '\n\t Ex: jaws module install ' + '\n\nupdate: update aws-module' + '\n\t Ex: jaws module update ' + '\n\ncreate: create aws-module action. Module will be created if DNE. create ' + '\n\t Ex: jaws module create users list' ) .option('-n, --no-save', '[install,update]: DONT merge awsm\'s CloudFormation extensions to your project') .option('-d, --dont-install-dependencies', '[install,update]: DONT install awsm\'s depdencies automatically') .option('-l, --lambda', '[create]: create lambda. Default is create lambda and endpoint.') .option('-e, --endpoint', '[create]: create API Gateway endpoint. Default is create lambda and endpoint.') .option('-r, --runtime ', '[create]: lambda runtime. Default nodejs') .action(function(cmd, params, options) { var theParams = process.argv.slice(3); if (!theParams) { throw new JawsError('Missing params', JawsError.errorCodes.UNKNOWN); } if (theParams[0][0] == '-') { //TODO: how do we get around this commander shortcoming? throw new JawsError('Specify options after cmd', JawsError.errorCodes.UNKNOWN); } if (cmd == 'install' || cmd == 'update') { //TODO: iterate thru cmds to see how many are before - if (theParams.length < 2) { throw new JawsError('Please specify awsm url', JawsError.errorCodes.UNKNOWN); } var url = theParams[1], theCmd = require('../lib/commands/module_install'); execute(theCmd[cmd](JAWS, url, options.save, options.dontInstallDependencies)); } else if (cmd == 'create') { if (theParams.length < 3) { throw new JawsError('Please specify awsm resource and action name'); } var theCmd = require('../lib/commands/module_create'); var module = { name: theParams[1], action: theParams[2], runtime: options.runtime || 'nodejs' }; if (options.lambda) { module.type = 'lambda'; } else if (options.endpoint) { module.type = 'endpoint'; } else { module.type = 'both'; } execute(theCmd.run(JAWS, module)); } else { console.error('Unsupported cmd ' + cmd + '. Must be install|update|create'); process.exit(1); } }); /** * Tag * - Tag a lambda or endpoint for deployment */ program .command('tag ') .description('Tag lambda function, api gateway resource (endpoint), or both for deployment ' + 'the next time deploy command is run.') .option('-u, --untag', 'un-tag lambda|endpoint|both') .option('-a, --tag-all', 'tag all lambda|endpoint|both in project') .option('-l, --list-all', 'list all tagged lambda|endpoint|both in project') .option('-n, --untag-all', 'un-tag all lambda|endpoint|both in project') .action(function(type, options) { type = type.toLowerCase(); if (-1 == ['endpoint', 'lambda', 'both'].indexOf(type)) { console.error('Unsupported type ' + type + '. Must be endpoint|lambda|both'); process.exit(1); } var CmdTag = require('../lib/commands/tag'); if (options.listAll) { execute(CmdTag.listAll(JAWS, type).then(function(relPaths) { console.log(relPaths); })); } else if (options.tagAll || options.untagAll) { var untag = (options.untagAll) ? true : false; execute(CmdTag.tagAll(JAWS, type, untag)); } else { // If not tagging all, you have to be tagging whats in your CWD (null 1st param) execute(CmdTag.tag(type, null, options.untag)); } }); /** * Deploy * - Deploy Lambda or Endpoint */ program .command('deploy [stage] [region]') .description('Deploy a lambda function (type lambda), a REST API (endpoint), or provision AWS resources (resources) for the specified stage.' + ' By default will tag and deploy type at cwd') .option('-t, --tags', 'Deploy all lambdas tagged as deployable in their jaws.json. Default is to just deploy cwd') .option('-d, --dont-exe-cf', 'Don\'t execute the lambda cloudformation, just generate it. Zips will be uploaded to s3') .action(function(type, stage, region, options) { type = type.toLowerCase(); switch (type) { case 'endpoint': var allTagged = (options.tags) ? true : false; var theCmd = require('../lib/commands/deploy_endpoint'); execute(theCmd.run(JAWS, stage, region, allTagged)); break; case 'lambda': var allTagged = (options.tags) ? true : false; var theCmd = require('../lib/commands/deploy_lambda'); execute(theCmd.run(JAWS, stage, region, allTagged, options.dontExeCf)); break; case 'resources': var theCmd = require('../lib/commands/deploy_resources'); execute(theCmd.run(JAWS, stage, region)); break; default: console.error('Unsupported type ' + type + '. Must be endpoint|lambda|resources'); process.exit(1); break; } }); /** * Env * - Manage ENV variables for a stage */ program .command('env [key] [val]') .description('Manage env vars for stage & region. can be "all" can be "local"' + '\n\nValid \'s:' + '\n\nlist: vars for stage and region. jaws env list ' + '\n\t Ex: jaws env list prod all' + '\n\nget: var value for stage and region. jaws env get ' + '\n\t Ex: jaws env get prod all JAWS_STAGE' + '\n\nset: var value for stage and region. jaws set env ' + '\n\t Ex: jaws env set prod us-east-1 TABLE_NAME users' + '\n\nunset: var value for stage and region. jaws env unset ' + '\n\t Ex: jaws unset prod us-east-1 TABLE_NAME' ) .action(function(cmd, stage, region, key, val) { var CmdEnv = require('../lib/commands/env'); cmd = cmd.toLowerCase(); switch (cmd) { case 'list': execute(CmdEnv.listEnv(JAWS, stage, region, true)); break; case 'get': if (!key) { console.error('Must specify key to set'); process.exit(1); } execute(CmdEnv.getEnvKey(JAWS, stage, region, key)); break; case 'set': if (!key || typeof val == 'undefined') { console.error('Must specify key and value'); process.exit(1); } execute(CmdEnv.setEnvKey(JAWS, stage, region, key, val)); break; case 'unset': if (!key) { console.error('Must specify key to unset'); process.exit(1); } if (val) { console.error('Do not specify val for unset'); process.exit(1); } execute(CmdEnv.setEnvKey(JAWS, stage, region, key)); break; default: console.error('Unsupported cmd "' + cmd + '". Must be list|get|set|unset'); process.exit(1); break; } }); /** * Dash */ program .command('dash') .description('View a project summary and select resources to deploy.') .action(function() { var CmdDash = require('../lib/commands/dash'); execute(CmdDash.run(JAWS)); }); if (process.argv.length == 2) { program.outputHelp(); } else { program.parse(process.argv); if (program.verbose) { rawDebug.enable('jaws:*'); } }