mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Proxy support for plugin installer
This commit is contained in:
parent
43b66cea3c
commit
26dff17610
4 changed files with 184 additions and 3 deletions
|
@ -66,6 +66,20 @@ If plugins were installed as a different user and the server is not starting, th
|
|||
[source,shell]
|
||||
$ chown -R kibana:kibana /path/to/kibana/optimize
|
||||
|
||||
[float]
|
||||
=== Proxy support for plugin installation
|
||||
|
||||
Kibana supports plugin installation via a proxy. It uses the `http_proxy` and `https_proxy`
|
||||
environment variables to detect a proxy for HTTP and HTTPS URLs.
|
||||
|
||||
It also respects the `no_proxy` environment variable to exclude specific URLs from proxying.
|
||||
|
||||
You can specify the environment variable directly when installing plugins:
|
||||
|
||||
[source,shell]
|
||||
$ http_proxy="http://proxy.local:4242" bin/kibana-plugin install <package name or URL>
|
||||
|
||||
|
||||
== Updating & Removing Plugins
|
||||
|
||||
To update a plugin, remove the current version and reinstall the plugin.
|
||||
|
|
|
@ -133,6 +133,7 @@
|
|||
"h2o2": "5.1.1",
|
||||
"handlebars": "4.0.5",
|
||||
"hapi": "14.2.0",
|
||||
"http-proxy-agent": "1.0.0",
|
||||
"imports-loader": "0.6.4",
|
||||
"inert": "4.0.2",
|
||||
"jade": "1.11.0",
|
||||
|
@ -157,6 +158,7 @@
|
|||
"node-fetch": "1.3.2",
|
||||
"pegjs": "0.9.0",
|
||||
"postcss-loader": "1.2.1",
|
||||
"proxy-from-env": "1.0.0",
|
||||
"prop-types": "15.5.8",
|
||||
"pui-react-overlay-trigger": "7.5.4",
|
||||
"pui-react-tooltip": "7.5.4",
|
||||
|
|
|
@ -8,6 +8,7 @@ import Logger from '../../lib/logger';
|
|||
import { UnsupportedProtocolError } from '../../lib/errors';
|
||||
import { download, _downloadSingle, _getFilePath, _checkFilePathDeprecation } from '../download';
|
||||
import { join } from 'path';
|
||||
import http from 'http';
|
||||
|
||||
describe('kibana cli', function () {
|
||||
|
||||
|
@ -251,6 +252,150 @@ describe('kibana cli', function () {
|
|||
});
|
||||
});
|
||||
|
||||
after(function () {
|
||||
nock.cleanAll();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('proxy support', function () {
|
||||
|
||||
const proxyPort = 2626;
|
||||
const proxyUrl = `http://localhost:${proxyPort}`;
|
||||
|
||||
let proxyHit = false;
|
||||
|
||||
const proxy = http.createServer(function (req, res) {
|
||||
proxyHit = true;
|
||||
// Our test proxy simply returns an empty 200 response, since we only
|
||||
// care about the download promise being resolved.
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
});
|
||||
|
||||
function expectProxyHit() {
|
||||
expect(proxyHit).to.be(true);
|
||||
}
|
||||
|
||||
function expectNoProxyHit() {
|
||||
expect(proxyHit).to.be(false);
|
||||
}
|
||||
|
||||
function nockPluginForUrl(url) {
|
||||
nock(url)
|
||||
.get('/plugin.zip')
|
||||
.replyWithFile(200, join(__dirname, 'replies/test_plugin.zip'));
|
||||
}
|
||||
|
||||
before(function (done) {
|
||||
proxy.listen(proxyPort, done);
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
proxyHit = false;
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
delete process.env.http_proxy;
|
||||
delete process.env.https_proxy;
|
||||
delete process.env.no_proxy;
|
||||
});
|
||||
|
||||
it('should use http_proxy env variable', function () {
|
||||
process.env.http_proxy = proxyUrl;
|
||||
settings.urls = ['http://example.com/plugin.zip'];
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectProxyHit);
|
||||
});
|
||||
|
||||
it('should use https_proxy for secure URLs', function () {
|
||||
process.env.https_proxy = proxyUrl;
|
||||
settings.urls = ['https://example.com/plugin.zip'];
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectProxyHit);
|
||||
});
|
||||
|
||||
it('should not use http_proxy for HTTPS urls', function () {
|
||||
process.env.http_proxy = proxyUrl;
|
||||
settings.urls = ['https://example.com/plugin.zip'];
|
||||
|
||||
nockPluginForUrl('https://example.com');
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectNoProxyHit);
|
||||
});
|
||||
|
||||
it('should not use https_proxy for HTTP urls', function () {
|
||||
process.env.https_proxy = proxyUrl;
|
||||
settings.urls = ['http://example.com/plugin.zip'];
|
||||
|
||||
nockPluginForUrl('http://example.com');
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectNoProxyHit);
|
||||
});
|
||||
|
||||
it('should support domains in no_proxy', function () {
|
||||
process.env.http_proxy = proxyUrl;
|
||||
process.env.no_proxy = 'foo.bar, example.com';
|
||||
settings.urls = ['http://example.com/plugin.zip'];
|
||||
|
||||
nockPluginForUrl('http://example.com');
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectNoProxyHit);
|
||||
});
|
||||
|
||||
it('should support subdomains in no_proxy', function () {
|
||||
process.env.http_proxy = proxyUrl;
|
||||
process.env.no_proxy = 'foo.bar,plugins.example.com';
|
||||
settings.urls = ['http://plugins.example.com/plugin.zip'];
|
||||
|
||||
nockPluginForUrl('http://plugins.example.com');
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectNoProxyHit);
|
||||
});
|
||||
|
||||
it('should accept wildcard subdomains in no_proxy', function () {
|
||||
process.env.http_proxy = proxyUrl;
|
||||
process.env.no_proxy = 'foo.bar, .example.com';
|
||||
settings.urls = ['http://plugins.example.com/plugin.zip'];
|
||||
|
||||
nockPluginForUrl('http://plugins.example.com');
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectNoProxyHit);
|
||||
});
|
||||
|
||||
it('should support asterisk wildcard no_proxy syntax', function () {
|
||||
process.env.http_proxy = proxyUrl;
|
||||
process.env.no_proxy = '*.example.com';
|
||||
settings.urls = ['http://plugins.example.com/plugin.zip'];
|
||||
|
||||
nockPluginForUrl('http://plugins.example.com');
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectNoProxyHit);
|
||||
});
|
||||
|
||||
it('should support implicit ports in no_proxy', function () {
|
||||
process.env.https_proxy = proxyUrl;
|
||||
process.env.no_proxy = 'example.com:443';
|
||||
settings.urls = ['https://example.com/plugin.zip'];
|
||||
|
||||
nockPluginForUrl('https://example.com');
|
||||
|
||||
return download(settings, logger)
|
||||
.then(expectNoProxyHit);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
proxy.close(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -2,11 +2,31 @@ import Wreck from 'wreck';
|
|||
import Progress from '../progress';
|
||||
import { fromNode as fn } from 'bluebird';
|
||||
import { createWriteStream } from 'fs';
|
||||
import HttpProxyAgent from 'http-proxy-agent';
|
||||
import { getProxyForUrl } from 'proxy-from-env';
|
||||
|
||||
function sendRequest({ sourceUrl, timeout }) {
|
||||
function getProxyAgent(sourceUrl, logger) {
|
||||
const proxy = getProxyForUrl(sourceUrl);
|
||||
|
||||
if (!proxy) {
|
||||
return null;
|
||||
}
|
||||
|
||||
logger.log(`Picked up proxy ${proxy} from environment variable.`);
|
||||
return new HttpProxyAgent(proxy);
|
||||
}
|
||||
|
||||
function sendRequest({ sourceUrl, timeout }, logger) {
|
||||
const maxRedirects = 11; //Because this one goes to 11.
|
||||
return fn(cb => {
|
||||
const req = Wreck.request('GET', sourceUrl, { timeout, redirects: maxRedirects }, (err, resp) => {
|
||||
const reqOptions = { timeout, redirects: maxRedirects };
|
||||
const proxyAgent = getProxyAgent(sourceUrl, logger);
|
||||
|
||||
if (proxyAgent) {
|
||||
reqOptions.agent = proxyAgent;
|
||||
}
|
||||
|
||||
const req = Wreck.request('GET', sourceUrl, reqOptions, (err, resp) => {
|
||||
if (err) {
|
||||
if (err.code === 'ECONNREFUSED') {
|
||||
err = new Error('ENOTFOUND');
|
||||
|
@ -50,7 +70,7 @@ Responsible for managing http transfers
|
|||
*/
|
||||
export default async function downloadUrl(logger, sourceUrl, targetPath, timeout) {
|
||||
try {
|
||||
const { req, resp } = await sendRequest({ sourceUrl, timeout });
|
||||
const { req, resp } = await sendRequest({ sourceUrl, timeout }, logger);
|
||||
|
||||
try {
|
||||
const totalSize = parseFloat(resp.headers['content-length']) || 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue