Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 -- <elasticsearch_url>
aws-es-proxy <elasticsearch_url>
```

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 <profile_name> <elasticsearch_url>
docker run -it -v $HOME/.aws:/root/.aws --rm -p 9210:9200 \
aws-es-proxy --profile <profile_name> <elasticsearch_url>
```


## Related
* [aws-es-curl](https://github.com/joona/aws-es-curl)

140 changes: 72 additions & 68 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];

Expand All @@ -79,7 +89,7 @@ var readBody = function(request) {
});
};

var requestHandler = function(request, response) {
var requestHandler = function (request, response) {
var body = [];

request.on('data', chunk => {
Expand All @@ -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 => {
Expand All @@ -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;
Expand All @@ -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);
});

Expand Down