Skip to content

Commit

Permalink
Merge branch '7.11' into backport/7.11/pr-87898
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Jan 12, 2021
2 parents 830d311 + ab4b84a commit 231fc4e
Show file tree
Hide file tree
Showing 26 changed files with 386 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ export class VisualizeEmbeddableFactory
const saveOptions = {
confirmOverwrite: false,
returnToOrigin: true,
isTitleDuplicateConfirmed: true,
};
savedVis.title = title;
savedVis.copyOnSave = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
*/

import axios from 'axios';
import HttpProxyAgent from 'http-proxy-agent';
import { Logger } from '../../../../../../src/core/server';
import { addTimeZoneToDate, request, patch, getErrorMessage } from './axios_utils';
import { loggingSystemMock } from '../../../../../../src/core/server/mocks';
import { getProxyAgents } from './get_proxy_agents';

const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
jest.mock('axios');
const axiosMock = (axios as unknown) as jest.Mock;
Expand All @@ -27,6 +28,7 @@ describe('addTimeZoneToDate', () => {

describe('request', () => {
beforeEach(() => {
jest.resetAllMocks();
axiosMock.mockImplementation(() => ({
status: 200,
headers: { 'content-type': 'application/json' },
Expand Down Expand Up @@ -58,23 +60,57 @@ describe('request', () => {
});
});

test('it have been called with proper proxy agent', async () => {
test('it have been called with proper proxy agent for a valid url', async () => {
const proxySettings = {
proxyRejectUnauthorizedCertificates: true,
proxyUrl: 'https://localhost:1212',
};
const { httpAgent, httpsAgent } = getProxyAgents(proxySettings, logger);

const res = await request({
axios,
url: '/testProxy',
url: 'http://testProxy',
logger,
proxySettings: {
proxyUrl: 'http://localhost:1212',
proxyUrl: 'https://localhost:1212',
proxyRejectUnauthorizedCertificates: true,
},
});

expect(axiosMock).toHaveBeenCalledWith('http://testProxy', {
method: 'get',
data: {},
headers: undefined,
httpAgent,
httpsAgent,
params: undefined,
proxy: false,
validateStatus: undefined,
});
expect(res).toEqual({
status: 200,
headers: { 'content-type': 'application/json' },
data: { incidentId: '123' },
});
});

test('it have been called with proper proxy agent for an invalid url', async () => {
const res = await request({
axios,
url: 'https://testProxy',
logger,
proxySettings: {
proxyUrl: ':nope:',
proxyRejectUnauthorizedCertificates: false,
},
});

expect(axiosMock).toHaveBeenCalledWith('/testProxy', {
expect(axiosMock).toHaveBeenCalledWith('https://testProxy', {
method: 'get',
data: {},
headers: undefined,
httpAgent: new HttpProxyAgent('http://localhost:1212'),
httpsAgent: new HttpProxyAgent('http://localhost:1212'),
httpAgent: undefined,
httpsAgent: undefined,
params: undefined,
proxy: false,
validateStatus: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import { AxiosInstance, Method, AxiosResponse, AxiosBasicCredentials } from 'axios';
import { Logger } from '../../../../../../src/core/server';
import { ProxySettings } from '../../types';
import { getProxyAgent } from './get_proxy_agent';
import { getProxyAgents } from './get_proxy_agents';

export const request = async <T = unknown>({
axios,
Expand All @@ -32,15 +32,17 @@ export const request = async <T = unknown>({
validateStatus?: (status: number) => boolean;
auth?: AxiosBasicCredentials;
}): Promise<AxiosResponse> => {
const { httpAgent, httpsAgent } = getProxyAgents(proxySettings, logger);

return await axios(url, {
method,
data: data ?? {},
params,
auth,
// use httpsAgent and embedded proxy: false, to be able to handle fail on invalid certs
httpsAgent: proxySettings ? getProxyAgent(proxySettings, logger) : undefined,
httpAgent: proxySettings ? getProxyAgent(proxySettings, logger) : undefined,
proxy: false, // the same way as it done for IncomingWebhook in
// use httpAgent and httpsAgent and set axios proxy: false, to be able to handle fail on invalid certs
httpAgent,
httpsAgent,
proxy: false,
headers,
validateStatus,
});
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import HttpProxyAgent from 'http-proxy-agent';
import { HttpsProxyAgent } from 'https-proxy-agent';
import { Logger } from '../../../../../../src/core/server';
import { getProxyAgents } from './get_proxy_agents';
import { loggingSystemMock } from '../../../../../../src/core/server/mocks';
const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;

describe('getProxyAgents', () => {
test('get agents for valid proxy URL', () => {
const { httpAgent, httpsAgent } = getProxyAgents(
{ proxyUrl: 'https://someproxyhost', proxyRejectUnauthorizedCertificates: false },
logger
);
expect(httpAgent instanceof HttpProxyAgent).toBeTruthy();
expect(httpsAgent instanceof HttpsProxyAgent).toBeTruthy();
});

test('return undefined agents for invalid proxy URL', () => {
const { httpAgent, httpsAgent } = getProxyAgents(
{ proxyUrl: ':nope: not a valid URL', proxyRejectUnauthorizedCertificates: false },
logger
);
expect(httpAgent).toBe(undefined);
expect(httpsAgent).toBe(undefined);
});

test('return undefined agents for null proxy options', () => {
const { httpAgent, httpsAgent } = getProxyAgents(null, logger);
expect(httpAgent).toBe(undefined);
expect(httpsAgent).toBe(undefined);
});

test('return undefined agents for undefined proxy options', () => {
const { httpAgent, httpsAgent } = getProxyAgents(undefined, logger);
expect(httpAgent).toBe(undefined);
expect(httpsAgent).toBe(undefined);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { Agent } from 'http';
import HttpProxyAgent from 'http-proxy-agent';
import { HttpsProxyAgent } from 'https-proxy-agent';
import { Logger } from '../../../../../../src/core/server';
import { ProxySettings } from '../../types';

interface GetProxyAgentsResponse {
httpAgent: Agent | undefined;
httpsAgent: Agent | undefined;
}

export function getProxyAgents(
proxySettings: ProxySettings | undefined | null,
logger: Logger
): GetProxyAgentsResponse {
const undefinedResponse = {
httpAgent: undefined,
httpsAgent: undefined,
};

if (!proxySettings) {
return undefinedResponse;
}

logger.debug(`Creating proxy agents for proxy: ${proxySettings.proxyUrl}`);
let proxyUrl: URL;
try {
proxyUrl = new URL(proxySettings.proxyUrl);
} catch (err) {
logger.warn(`invalid proxy URL "${proxySettings.proxyUrl}" ignored`);
return undefinedResponse;
}

const httpAgent = new HttpProxyAgent(proxySettings.proxyUrl);
const httpsAgent = (new HttpsProxyAgent({
host: proxyUrl.hostname,
port: Number(proxyUrl.port),
protocol: proxyUrl.protocol,
headers: proxySettings.proxyHeaders,
// do not fail on invalid certs if value is false
rejectUnauthorized: proxySettings.proxyRejectUnauthorizedCertificates,
}) as unknown) as Agent;
// vsCode wasn't convinced HttpsProxyAgent is an http.Agent, so we convinced it

return { httpAgent, httpsAgent };
}
16 changes: 9 additions & 7 deletions x-pack/plugins/actions/server/builtin_action_types/slack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@

import { URL } from 'url';
import { curry } from 'lodash';
import { HttpsProxyAgent } from 'https-proxy-agent';
import HttpProxyAgent from 'http-proxy-agent';
import { Agent } from 'http';
import { i18n } from '@kbn/i18n';
import { schema, TypeOf } from '@kbn/config-schema';
import { IncomingWebhook, IncomingWebhookResult } from '@slack/webhook';
Expand All @@ -24,7 +23,7 @@ import {
ExecutorType,
} from '../types';
import { ActionsConfigurationUtilities } from '../actions_config';
import { getProxyAgent } from './lib/get_proxy_agent';
import { getProxyAgents } from './lib/get_proxy_agents';

export type SlackActionType = ActionType<{}, ActionTypeSecretsType, ActionParamsType, unknown>;
export type SlackActionTypeExecutorOptions = ActionTypeExecutorOptions<
Expand Down Expand Up @@ -128,18 +127,21 @@ async function slackExecutor(
const { webhookUrl } = secrets;
const { message } = params;

let proxyAgent: HttpsProxyAgent | HttpProxyAgent | undefined;
let httpProxyAgent: Agent | undefined;
if (execOptions.proxySettings) {
proxyAgent = getProxyAgent(execOptions.proxySettings, logger);
const httpProxyAgents = getProxyAgents(execOptions.proxySettings, logger);
httpProxyAgent = webhookUrl.toLowerCase().startsWith('https')
? httpProxyAgents.httpsAgent
: httpProxyAgents.httpAgent;

logger.debug(`IncomingWebhook was called with proxyUrl ${execOptions.proxySettings.proxyUrl}`);
}

try {
// https://slack.dev/node-slack-sdk/webhook
// node-slack-sdk use Axios inside :)
const webhook = new IncomingWebhook(webhookUrl, {
// @ts-expect-error The types exposed by 'HttpsProxyAgent' isn't up to date with 'Agent'
agent: proxyAgent,
agent: httpProxyAgent,
});
result = await webhook.send(message);
} catch (err) {
Expand Down
Loading

0 comments on commit 231fc4e

Please sign in to comment.