index.js (167 lines of code) (raw):
import { ProxyConfigCollection } from './server/proxy_config_collection';
module.exports = function (kibana) {
let { resolve, join, sep } = require('path');
let Joi = require('joi');
let Boom = require('boom');
let modules = resolve(__dirname, 'public/webpackShims/');
let src = resolve(__dirname, 'public/src/');
let { existsSync } = require('fs');
const { startsWith, endsWith } = require('lodash');
const apps = [
{
title: 'Sense',
description: 'JSON aware developer\'s interface to ElasticSearch',
icon: 'plugins/sense/bonsai.png',
main: 'plugins/sense/sense',
injectVars: function (server, options) {
return options;
}
}
];
if (existsSync(resolve(__dirname, 'public/tests'))) {
apps.push({
title: 'Sense Tests',
id: 'sense-tests',
main: 'plugins/sense/tests',
hidden: true
//listed: false // uncomment after https://github.com/elastic/kibana/pull/4755
});
}
return new kibana.Plugin({
id: 'sense',
config: function (Joi) {
return Joi.object({
enabled: Joi.boolean().default(true),
defaultServerUrl: Joi.string().default('http://localhost:9200'),
proxyFilter: Joi.array().items(Joi.string()).single().default(['.*']),
ssl: Joi.object({
verify: Joi.boolean(),
}).default(),
proxyConfig: Joi.array().items(
Joi.object().keys({
match: Joi.object().keys({
protocol: Joi.string().default('*'),
host: Joi.string().default('*'),
port: Joi.string().default('*'),
path: Joi.string().default('*')
}),
timeout: Joi.number(),
ssl: Joi.object().keys({
verify: Joi.boolean(),
ca: Joi.array().single().items(Joi.string()),
cert: Joi.string(),
key: Joi.string()
}).default()
})
).default([
{
match: {
protocol: '*',
host: '*',
port: '*',
path: '*'
},
timeout: 180000,
ssl: {
verify: true
}
}
])
}).default();
},
init: function (server, options) {
const filters = options.proxyFilter.map(str => new RegExp(str));
if (options.ssl && options.ssl.verify) {
throw new Error('sense.ssl.version is no longer supported.');
}
const proxyConfigCollection = new ProxyConfigCollection(options.proxyConfig);
const proxyRouteConfig = {
validate: {
query: Joi.object().keys({
uri: Joi.string().uri({
allowRelative: false,
shema: ['http:', 'https:'],
}),
}).unknown(true),
},
pre: [
function filterUri(req, reply) {
const { uri } = req.query;
if (!filters.some(re => re.test(uri))) {
const err = Boom.forbidden();
err.output.payload = "Error connecting to '" + uri + "':\n\nUnable to send requests to that url.";
err.output.headers['content-type'] = 'text/plain';
reply(err);
} else {
reply();
}
}
],
handler(req, reply) {
const { uri } = req.query;
reply.proxy({
uri,
xforward: true,
passThrough: true,
onResponse(err, res, request, reply, settings, ttl) {
if (err != null) {
reply("Error connecting to '" + request.query.uri + "':\n\n" + err.message).type("text/plain").statusCode = 502;
} else {
reply(null, res);
}
},
...proxyConfigCollection.configForUri(uri)
})
}
};
server.route({
path: '/api/sense/proxy',
method: '*',
config: {
...proxyRouteConfig,
payload: {
output: 'stream',
parse: false
},
}
});
server.route({
path: '/api/sense/proxy',
method: 'GET',
config: {
...proxyRouteConfig
}
})
server.route({
path: '/api/sense/api_server',
method: ['GET', 'POST'],
handler: function (req, reply) {
let server = require('./api_server/server');
let {sense_version, apis} = req.query;
if (!apis) {
reply(Boom.badRequest('"apis" is a required param.'));
return;
}
return server.resolveApi(sense_version, apis.split(","), reply);
}
});
const testApp = kibana.uiExports.apps.hidden.byId['sense-tests'];
if (testApp) {
server.route({
path: '/app/sense-tests',
method: 'GET',
handler: function (req, reply) {
return reply.renderApp(testApp);
}
});
}
},
uiExports: {
apps: apps,
noParse: [
join(modules, 'ace' + sep),
join(modules, 'moment_src/moment' + sep),
join(src, 'sense_editor/mode/worker.js')
]
}
})
};