Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add proxy support for plugin installation #7967

Closed
wants to merge 4 commits into from
Closed
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
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,7 @@
"validate-npm-package-name": "2.2.2",
"webpack": "1.12.15",
"webpack-directory-name-as-main": "1.0.0",
"whatwg-fetch": "0.9.0",
"wreck": "6.2.0"
"whatwg-fetch": "0.9.0"
},
"devDependencies": {
"@elastic/eslint-config-kibana": "0.0.3",
Expand Down
2 changes: 1 addition & 1 deletion src/cli_plugin/install/download.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function _downloadSingle(settings, logger, sourceUrl) {
if (/^file/.test(urlInfo.protocol)) {
downloadPromise = downloadLocalFile(logger, decodeURI(urlInfo.path), settings.tempArchiveFile);
} else if (/^https?/.test(urlInfo.protocol)) {
downloadPromise = downloadHttpFile(logger, sourceUrl, settings.tempArchiveFile, settings.timeout);
downloadPromise = downloadHttpFile(logger, sourceUrl, settings.tempArchiveFile, settings.timeout, settings.proxy);
} else {
downloadPromise = Promise.reject(new UnsupportedProtocolError());
}
Expand Down
42 changes: 26 additions & 16 deletions src/cli_plugin/install/downloaders/http.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import Wreck from 'wreck';
import Progress from '../progress';
import { fromNode as fn } from 'bluebird';
import Request from 'request';
import { createWriteStream, unlinkSync } from 'fs';

function sendRequest({ sourceUrl, timeout }) {
const maxRedirects = 11; //Because this one goes to 11.
return fn(cb => {
const req = Wreck.request('GET', sourceUrl, { timeout, redirects: maxRedirects }, (err, resp) => {
if (err) {
if (err.code === 'ECONNREFUSED') {
err = new Error('ENOTFOUND');
}

return cb(err);
}
function sendRequest({ sourceUrl, reqOptions }) {
return new Promise((resolve, reject) => {
const req = Request.get(sourceUrl, reqOptions);

req.on('response', (resp) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resp can be used without () as its a single argument

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ppisljar good to know. But I think it's better this way for coding style consistency, as it's write like that in the rest of code base.

if (resp.statusCode >= 400) {
return cb(new Error('ENOTFOUND'));
return reject(new Error('ENOTFOUND'));
}
return resolve({ req, resp });
});

cb(null, { req, resp });
req.on('error', (err) => {
if (err.code === 'ECONNREFUSED') {
err = new Error('ENOTFOUND');
}
return reject(err);
});
});
}
Expand Down Expand Up @@ -48,9 +47,20 @@ function downloadResponse({ resp, targetPath, progress }) {
/*
Responsible for managing http transfers
*/
export default async function downloadUrl(logger, sourceUrl, targetPath, timeout) {
export default async function downloadUrl(logger, sourceUrl, targetPath, timeout, proxy) {
const reqOptions = {
'timeout': timeout,
'maxRedirects': 11, //Because this one goes to 11.
'encoding': null
};

if (proxy) {
reqOptions.proxy = proxy;
logger.log(`Attempting to use the following proxy: ${proxy}`);
}

try {
const { req, resp } = await sendRequest({ sourceUrl, timeout });
const { req, resp } = await sendRequest({ sourceUrl, reqOptions });

try {
let totalSize = parseFloat(resp.headers['content-length']) || 0;
Expand Down
7 changes: 6 additions & 1 deletion src/cli_plugin/install/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import install from './install';
import Logger from '../lib/logger';
import pkg from '../../utils/package_json';
import { getConfig } from '../../server/path';
import { parse, parseMilliseconds } from './settings';
import { parse, parseMilliseconds, parseProxy } from './settings';
import { find } from 'lodash';

function processCommand(command, options) {
Expand Down Expand Up @@ -41,6 +41,11 @@ export default function pluginInstall(program) {
'path to the directory where plugins are stored',
fromRoot('plugins')
)
.option(
'--proxy <url>',
'proxy url to use',
parseProxy
)
.description('install a plugin',
`Common examples:
install x-pack
Expand Down
13 changes: 12 additions & 1 deletion src/cli_plugin/install/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ export function parseMilliseconds(val) {
return result;
};

export function parseProxy(val) {
const result = val.trim();
const regexp = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
if (!regexp.test(result)) {
throw new Error(`Invalid proxy name ${result}`);
}

return result;
}

export function parse(command, options, kbnPackage) {
const settings = {
timeout: options.timeout || 0,
Expand All @@ -31,7 +41,8 @@ export function parse(command, options, kbnPackage) {
config: options.config || '',
plugin: command,
version: kbnPackage.version,
pluginDir: options.pluginDir || ''
pluginDir: options.pluginDir || '',
proxy: options.proxy || ''
};

settings.urls = generateUrls(settings);
Expand Down
4 changes: 2 additions & 2 deletions tasks/build/download_node_builds.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = function (grunt) {
let { createGunzip } = require('zlib');
let { Extract } = require('tar');
let { rename } = require('fs');
let wreck = require('wreck');
let request = require('request');

let platforms = grunt.config.get('platforms');
let activeDownloads = [];
Expand All @@ -21,7 +21,7 @@ module.exports = function (grunt) {
}

let resp = await fromNode(cb => {
let req = wreck.request('GET', platform.nodeUrl, null, function (err, resp) {
let req = request.get(platform.nodeUrl, function (err, resp) {
if (err) {
return cb(err);
}
Expand Down