diff --git a/Dockerfile b/Dockerfile index b175d2d..2fdc6ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM node:6 +FROM node:6.11 -ENV TINI_VERSION v0.14.0 +ENV TINI_VERSION v0.15.0 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app @@ -14,5 +14,3 @@ COPY . /usr/src/app ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod +x /tini ENTRYPOINT ["/tini", "bin/aws-es-proxy", "--"] - -EXPOSE 9200 diff --git a/README.md b/README.md index 3cbf235..1ef9899 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Easily utilise `curl`, Sense and other tools of your liking to get answers from your AWS hosted ElasticSearch Service while developing or debugging. -`aws-es-proxy` is a dead simple local proxy, that knows how to sign your requests and talk to a hosted AWS ElasticSearch Service. +`aws-es-proxy` is a dead simple local proxy, that knows how to sign your requests and talk to a hosted AWS ElasticSearch Service. ## Prequisities @@ -50,17 +50,16 @@ Run and specify credentials via ENV variables. docker run -it --rm -p 9210:9200 \ -e AWS_ACCESS_KEY_ID=... \ -e AWS_SECRET_ACCESS_KEY=... \ - aws-es-proxy -- + aws-es-proxy ``` -Utilise configuration and profiles from the host. +Utilise configuration and profiles from the host. ``` -docker run -it -v $HOME/.aws:/root/.aws --rm -p 9210:9200 \ - aws-es-proxy -- --profile +docker run -it -v $HOME/.aws:/root/.aws --rm -p 9210:9200 \ + aws-es-proxy --profile ``` ## Related * [aws-es-curl](https://github.com/joona/aws-es-curl) - diff --git a/index.js b/index.js index e2c5e53..78ce0f0 100644 --- a/index.js +++ b/index.js @@ -2,69 +2,79 @@ const AWS = require('aws-sdk'); const co = require('co'); const url = require('url'); const http = require('http'); -const options = require('optimist') - .argv; +const options = require('optimist').argv; const context = {}; -const profile = process.env.AWS_PROFILE || options.profile || 'default'; - +process.env.AWS_PROFILE = process.env.AWS_PROFILE || options.profile || 'default'; var creds = {}; -AWS.CredentialProviderChain.defaultProviders = [ - () => { return new AWS.EnvironmentCredentials('AWS'); }, - () => { return new AWS.EnvironmentCredentials('AMAZON'); }, - () => { return new AWS.SharedIniFileCredentials({ profile: profile }); }, - () => { return new AWS.EC2MetadataCredentials(); } -]; - -var execute = function(endpoint, region, path, method, body) { - return new Promise((resolve, reject) => { - var req = new AWS.HttpRequest(endpoint); - console.log('AWS HTTP Request:', method, path); - - - req.method = method || 'GET'; - req.path = path; - req.region = region; - if(body) { - if(typeof body === "object") { - req.body = JSON.stringify(body); - } else { - req.body = body; +var updateCredentials = function () { + return new Promise(function (resolve, reject) { + AWS.config.getCredentials(function (err) { + if(err) { + console.log('Error while getting Credentials.'); + console.log(err); + reject(err) } - } - - // Sense likes send GET request with body, which aws-sdk doesn't really allow. Translate to POST instead. - if(req.body && req.method == 'GET') { - req.method = 'POST'; - } - - req.headers['presigned-expires'] = false; - req.headers.Host = endpoint.host; - - var signer = new AWS.Signers.V4(req, 'es'); - signer.addAuthorization(creds, new Date()); + resolve() + }) + }); +} - var send = new AWS.NodeHttpClient(); - send.handleRequest(req, null, (httpResp) => { - var body = ''; - httpResp.on('data', (chunk) => { - body += chunk; - }); - httpResp.on('end', (chunk) => { - resolve({ - statusCode: httpResp.statusCode, - body: body +var execute = function (endpoint, region, path, method, body) { + return new Promise((resolve, reject) => { + co(function* () { + + var req = new AWS.HttpRequest(endpoint); + console.log('AWS HTTP Request:', method, path); + + req.method = method || 'GET'; + req.path = path; + req.region = region; + + if(body) { + if(typeof body === "object") { + req.body = JSON.stringify(body); + } else { + req.body = body; + } + } + + // Sense likes send GET request with body, which aws-sdk doesn't really allow. Translate to POST instead. + if(req.body && req.method == 'GET') { + req.method = 'POST'; + } + + req.headers['presigned-expires'] = false; + req.headers.Host = endpoint.host; + + // Some credentials may require refresh, updateCredentials handles this + yield updateCredentials() + var signer = new AWS.Signers.V4(req, 'es'); + signer.addAuthorization(AWS.config.credentials, new Date()); + + var send = new AWS.NodeHttpClient(); + send.handleRequest(req, null, (httpResp) => { + var body = ''; + httpResp.on('data', (chunk) => { + body += chunk; + }); + httpResp.on('end', (chunk) => { + resolve({ + statusCode: httpResp.statusCode, + body: body + }); + }); + }, (err) => { + console.log('Error: ' + err); + reject(err); }); - }); - }, (err) => { - console.log('Error: ' + err); - reject(err); - }); + }) + .catch(err => reject(err)) }); }; -var readBody = function(request) { +var readBody = function (request) { return new Promise(resolve => { var body = []; @@ -79,7 +89,7 @@ var readBody = function(request) { }); }; -var requestHandler = function(request, response) { +var requestHandler = function (request, response) { var body = []; request.on('data', chunk => { @@ -90,7 +100,7 @@ var requestHandler = function(request, response) { var buf = Buffer.concat(body).toString(); console.log('Body:', buf); - co(function*(){ + co(function* () { return yield execute(context.endpoint, context.region, request.url, request.method, buf); }) .then(resp => { @@ -109,18 +119,17 @@ var requestHandler = function(request, response) { var server = http.createServer(requestHandler); -var startServer = function() { +var startServer = function () { return new Promise((resolve) => { - server.listen(context.port, function(){ + server.listen(context.port, function () { console.log('Listening on', context.port); resolve(); }); }); }; - -var main = function() { - co(function*(){ +var main = function () { + co(function* () { var maybeUrl = options._[0]; context.region = options.region || 'eu-west-1'; context.port = options.port || 9200; @@ -140,14 +149,9 @@ var main = function() { context.endpoint = new AWS.Endpoint(uri.host); } - var chain = new AWS.CredentialProviderChain(); - yield chain.resolvePromise() - .then(function (credentials) { - creds = credentials; - }) - .catch(function (err) { - console.log('Error while getting AWS Credentials.') - console.log(err); + yield updateCredentials() + .catch(err => { + // if we cannot find credentials, exit process.exit(1); });