From 37e464264d477684e0ded6151b3a4e3500eee269 Mon Sep 17 00:00:00 2001 From: David Von Lehman Date: Mon, 22 Jun 2015 10:06:05 -0700 Subject: [PATCH] Auto recognize https_proxy environment variable and eliminate requirement to explicitly pass in AWS credentials and instead let the SDK discover them via it's built-in mechanisms. --- Readme.md | 37 +++++++++++++++++++------------------ index.js | 35 +++++++++++++++++++++++++---------- package.json | 1 + 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/Readme.md b/Readme.md index f1d78e3..07d1e45 100644 --- a/Readme.md +++ b/Readme.md @@ -13,30 +13,30 @@ This package uses the [aws-sdk (node)](http://aws.amazon.com/sdk-for-node-js/). ## Usage -Put in your AWS Developer key/secret. These are required, or else the plugin doesn't have access to the bucket you want to upload to. - ```js var gulp = require('gulp'); - var s3 = require('gulp-s3-upload')({ - accessKeyId: "YOUR DEV ID", - secretAccessKey: "YOUR SECRET" - }); + var s3 = require('gulp-s3-upload')(config); ``` -The other options not mentioned above (like `region`) available in the [AWS Config Constructor](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html#constructor-property) are also available, though by default are `undefined`. -Option names `key` and `secret` are also alternative option names, though the use of `accessKeyId` and `secretAccessKey` are encouraged to match the AWS Config Constructor. +The optional `config` argument can include any option available (like `region`) available in the [AWS Config Constructor](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html#constructor-property). By default all settings are undefined. + +Per AWS best practices, the recommended approach for loading credentials is to use the shared credentials file (`~/.aws/credentials`). You can also set the `aws_access_key_id` and `aws_secret_access_key` environment variables or specify values directly in the gulpfile via the `accessKeyId` and `secretAccessKey` options. If you have multiple profiles configured in your AWS credentials file, you can specify the profile name inline with the call to gulp. + +```sh +AWS_PROFILE=myprofile gulp +``` Create a task. ```js - gulp.task("upload", function() { - gulp.src("./dir/to/upload/**") - .pipe(s3({ - Bucket: 'your-bucket-name', // Required - ACL: 'public-read' // Needs to be user-defined - })) - ; - }); +gulp.task("upload", function() { + gulp.src("./dir/to/upload/**") + .pipe(s3({ + Bucket: 'your-bucket-name', // Required + ACL: 'public-read' // Needs to be user-defined + })) + ; +}); ``` ## Options @@ -114,7 +114,7 @@ precedence and be added to each file being uploaded. Example (passing a `function`): -```js +```js // ... setup gulp-s3-upload ... var path = require('path'); var metadata_collection = { @@ -144,7 +144,7 @@ When passing a function, it's important to note that the file will already be transformed either by the `keyTransform` you defined or by the default function which creates a keyname relative to your S3 bucket, e.g. you can get "example.txt" or "docs/example.txt" -depending on how it was structured locally (hence why in the example, +depending on how it was structured locally (hence why in the example, the `path` module is used to just get the filename). **Note:** You should be responsible for handling mismatching/unmatched keynames @@ -183,6 +183,7 @@ overwrite existing ones. ## AWS-SDK References * [AWS Config Constructor](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html#constructor-property) +* [Configuring the AWS Node.js SDK](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html) * [S3 putObject](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property) * [Access Control List (ACL) Overview](http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html) diff --git a/index.js b/index.js index 25b00fb..40fce4f 100644 --- a/index.js +++ b/index.js @@ -109,7 +109,7 @@ gulpPrefixer = function (AWS) { var objOpts; if(getErr && getErr.statusCode !== 404) { - return callback(new gutil.PluginError(PLUGIN_NAME, "S3 Error: " + getErr.message)); + return callback(new gutil.PluginError(PLUGIN_NAME, "S3 headObject Error: " + getErr.stack)); } objOpts = helper.filterOptions(options); @@ -124,7 +124,7 @@ gulpPrefixer = function (AWS) { _s3.putObject(objOpts, function (err, data) { if(err) { - return callback(new gutil.PluginError(PLUGIN_NAME, "S3 Error: " + err.message)); + return callback(new gutil.PluginError(PLUGIN_NAME, "S3 putObject Error: " + err.stack)); } if(getData) { @@ -155,15 +155,30 @@ gulpPrefixer = function (AWS) { module.exports = function (config) { var aws_config = config || {}; - aws_config.accessKeyId = config.accessKeyId || config.key; - aws_config.secretAccessKey = config.secretAccessKey || config.secret; - - - if(!aws_config.accessKeyId || !aws_config.secretAccessKey) { - throw new PluginError(PLUGIN_NAME, "Missing AWS Key & Secret."); + // Maintain backwards compatibility with legacy key and secret options + if (config.key) + aws_config.accessKeyId = config.key; + if (config.secret) + aws_config.secretAccessKey = config.secret; + + // Intentionally not mandating the accessKeyId and secretAccessKey as they + // will be loaded automatically by the SDK from either environment variables + // or the credentials file. + // http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html + + // Configure the proxy if an environment variable is present. + if (process.env.HTTPS_PROXY) { + gutil.log("setting https proxy to %s", process.env.HTTPS_PROXY); + if (!aws_config.httpOptions) + aws_config.httpOptions = {}; + + var HttpsProxyAgent = require('https-proxy-agent'); + aws_config.httpOptions.agent = new HttpsProxyAgent(process.env.HTTPS_PROXY); } - AWS.config.update(aws_config); + // Update the global AWS config if we have any overrides + if (Object.keys(aws_config).length) + AWS.config.update(aws_config); return gulpPrefixer(AWS); -}; \ No newline at end of file +}; diff --git a/package.json b/package.json index f8da03a..c2becbd 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "dependencies": { "aws-sdk": "2.1.17", "gulp-util": "^3.0.4", + "https-proxy-agent": "^0.3.5", "mime": "1.3.4", "through2": "0.6.3", "underscore": "1.8.2"