diff --git a/src/plugins/elasticsearch/lib/call_with_request.js b/src/plugins/elasticsearch/lib/call_with_request.js new file mode 100644 index 000000000000..5df624faea93 --- /dev/null +++ b/src/plugins/elasticsearch/lib/call_with_request.js @@ -0,0 +1,20 @@ +const _ = require('lodash'); +const Promise = require('bluebird'); +const Boom = require('boom'); +module.exports = (client) => { + return (req, endpoint, params = {}) => { + if (req.headers.authorization) { + _.set(params, 'headers.authorization', req.headers.authorization); + } + const api = _.get(client, endpoint); + if (!api) throw new Error(`callWithRequest called with an invalid endpoint: ${endpoint}`); + return api.call(client, params) + .catch((err) => { + if (err.status === 401) { + const options = { realm: 'Authorization Required' }; + return Promise.reject(Boom.unauthorized(err.body, 'Basic', options)); + } + return Promise.reject(err); + }); + }; +}; diff --git a/src/plugins/elasticsearch/lib/expose_client.js b/src/plugins/elasticsearch/lib/expose_client.js index c0a4972ee35c..c5b683ea19f7 100644 --- a/src/plugins/elasticsearch/lib/expose_client.js +++ b/src/plugins/elasticsearch/lib/expose_client.js @@ -3,51 +3,70 @@ var _ = require('lodash'); var fs = require('fs'); var util = require('util'); var url = require('url'); +var callWithRequest = require('./call_with_request'); module.exports = function (server) { var config = server.config(); - var uri = url.parse(config.get('elasticsearch.url')); - var username = config.get('elasticsearch.username'); - var password = config.get('elasticsearch.password'); - var verifySsl = config.get('elasticsearch.ssl.verify'); - var clientCrt = config.get('elasticsearch.ssl.cert'); - var clientKey = config.get('elasticsearch.ssl.key'); - var ca = config.get('elasticsearch.ssl.ca'); - var apiVersion = config.get('elasticsearch.apiVersion'); - if (username && password) { - uri.auth = util.format('%s:%s', username, password); - } + function createClient(options) { + options = _.defaults(options || {}, { + url: config.get('elasticsearch.url'), + username: config.get('elasticsearch.username'), + password: config.get('elasticsearch.password'), + verifySsl: config.get('elasticsearch.ssl.verify'), + clientCrt: config.get('elasticsearch.ssl.cert'), + clientKey: config.get('elasticsearch.ssl.key'), + ca: config.get('elasticsearch.ssl.ca'), + apiVersion: config.get('elasticsearch.apiVersion'), + keepAlive: true, + auth: true + }); - var ssl = { rejectUnauthorized: verifySsl }; - if (clientCrt && clientKey) { - ssl.cert = fs.readFileSync(clientCrt, 'utf8'); - ssl.key = fs.readFileSync(clientKey, 'utf8'); - } - if (ca) { - ssl.ca = fs.readFileSync(ca, 'utf8'); - } + var uri = url.parse(options.url); - var client = new elasticsearch.Client({ - host: url.format(uri), - ssl: ssl, - apiVersion: apiVersion, - log: function () { - this.error = function (err) { - server.log(['error', 'elasticsearch'], err); - }; - this.warning = function (message) { - server.log(['warning', 'elasticsearch'], message); - }; - this.info = _.noop; - this.debug = _.noop; - this.trace = _.noop; - this.close = _.noop; + var authorization; + if (options.auth && options.username && options.password) { + uri.auth = util.format('%s:%s', options.username, options.password); } - }); + var ssl = { rejectUnauthorized: options.verifySsl }; + if (options.clientCrt && options.clientKey) { + ssl.cert = fs.readFileSync(options.clientCrt, 'utf8'); + ssl.key = fs.readFileSync(options.clientKey, 'utf8'); + } + if (options.ca) { + ssl.ca = fs.readFileSync(options.ca, 'utf8'); + } + + return new elasticsearch.Client({ + host: url.format(uri), + ssl: ssl, + apiVersion: options.apiVersion, + keepAlive: options.keepAlive, + log: function () { + this.error = function (err) { + server.log(['error', 'elasticsearch'], err); + }; + this.warning = function (message) { + server.log(['warning', 'elasticsearch'], message); + }; + this.info = _.noop; + this.debug = _.noop; + this.trace = _.noop; + this.close = _.noop; + } + }); + } + + var client = createClient(); server.on('close', _.bindKey(client, 'close')); + + var noAuthClient = createClient({ auth: false }); + server.on('close', _.bindKey(noAuthClient, 'close')); + server.expose('client', client); + server.expose('createClient', createClient); + server.expose('callWithRequest', callWithRequest(noAuthClient)); return client;