mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ResponseOps][Connectors] Common request axios utility function across frameworks (#139549)
* Adding common axios util * Fixing tests * Removing patch * Moving config to be first param
This commit is contained in:
parent
f9e4c64f03
commit
eee492ab7e
30 changed files with 90 additions and 230 deletions
|
@ -8,15 +8,15 @@
|
|||
import axios, { AxiosError, AxiosResponse } from 'axios';
|
||||
|
||||
import { createExternalService } from './service';
|
||||
import { request, createAxiosResponse } from '../lib/axios_utils';
|
||||
import { request, createAxiosResponse } from '../../lib/axios_utils';
|
||||
import { CasesWebhookMethods, CasesWebhookPublicConfigurationType, ExternalService } from './types';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
import { actionsConfigMock } from '../../actions_config.mock';
|
||||
const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
|
||||
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
jest.mock('../../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -31,7 +31,7 @@ import {
|
|||
} from './types';
|
||||
|
||||
import * as i18n from './translations';
|
||||
import { request } from '../lib/axios_utils';
|
||||
import { request } from '../../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
|
||||
export const createExternalService = (
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { AxiosResponse, AxiosError } from 'axios';
|
||||
import { isEmpty, isObjectLike, get } from 'lodash';
|
||||
import { getErrorMessage } from '../lib/axios_utils';
|
||||
import { getErrorMessage } from '../../lib/axios_utils';
|
||||
import * as i18n from './translations';
|
||||
|
||||
export const createServiceError = (error: AxiosError, message: string) => {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import axios from 'axios';
|
||||
|
||||
import { createExternalService } from './service';
|
||||
import { request, createAxiosResponse } from '../lib/axios_utils';
|
||||
import { request, createAxiosResponse } from '../../lib/axios_utils';
|
||||
import { ExternalService } from './types';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
@ -20,8 +20,8 @@ interface ResponseError extends Error {
|
|||
}
|
||||
|
||||
jest.mock('axios');
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
jest.mock('../../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
} from './types';
|
||||
|
||||
import * as i18n from './translations';
|
||||
import { request, getErrorMessage, throwIfResponseIsNotValid } from '../lib/axios_utils';
|
||||
import { request, getErrorMessage, throwIfResponseIsNotValid } from '../../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
|
||||
const VERSION = '2';
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import axios, { AxiosResponse } from 'axios';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { Services } from '../../types';
|
||||
import { request } from './axios_utils';
|
||||
import { request } from '../../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
|
||||
interface PostPagerdutyOptions {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { request } from './axios_utils';
|
||||
import { request } from '../../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
|
||||
interface PostXmattersOptions {
|
||||
|
|
|
@ -9,7 +9,7 @@ import qs from 'query-string';
|
|||
import axios from 'axios';
|
||||
import stringify from 'json-stable-stringify';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { request } from './axios_utils';
|
||||
import { request } from '../../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
import { AsApiContract } from '../../../common';
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import stringify from 'json-stringify-safe';
|
||||
import axios, { AxiosInstance, AxiosResponse } from 'axios';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { request } from './axios_utils';
|
||||
import { request } from '../../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
import { SendEmailOptions } from './send_email';
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import axios from 'axios';
|
||||
|
||||
import { createExternalService, getValueTextContent, formatUpdateRequest } from './service';
|
||||
import { request, createAxiosResponse } from '../lib/axios_utils';
|
||||
import { request, createAxiosResponse } from '../../lib/axios_utils';
|
||||
import { ExternalService } from './types';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
@ -18,8 +18,8 @@ import { actionsConfigMock } from '../../actions_config.mock';
|
|||
const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
|
||||
|
||||
jest.mock('axios');
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
jest.mock('../../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -24,7 +24,7 @@ import {
|
|||
} from './types';
|
||||
|
||||
import * as i18n from './translations';
|
||||
import { getErrorMessage, request, throwIfResponseIsNotValid } from '../lib/axios_utils';
|
||||
import { getErrorMessage, request, throwIfResponseIsNotValid } from '../../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
|
||||
const VIEW_INCIDENT_URL = `#incidents`;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import axios, { AxiosResponse } from 'axios';
|
||||
|
||||
import { createExternalService } from './service';
|
||||
import * as utils from '../lib/axios_utils';
|
||||
import * as utils from '../../lib/axios_utils';
|
||||
import { ExternalService, ServiceNowITSMIncident } from './types';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
@ -18,8 +18,8 @@ import { snExternalServiceConfig } from './config';
|
|||
const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
|
||||
|
||||
jest.mock('axios');
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
jest.mock('../../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
|
||||
import * as i18n from './translations';
|
||||
import { ServiceNowPublicConfigurationType, ServiceNowSecretConfigurationType } from './types';
|
||||
import { request } from '../lib/axios_utils';
|
||||
import { request } from '../../lib/axios_utils';
|
||||
import { createServiceError, getPushedDate, prepareIncident } from './utils';
|
||||
|
||||
export const SYS_DICTIONARY_ENDPOINT = `api/now/table/sys_dictionary`;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import axios from 'axios';
|
||||
|
||||
import { createExternalServiceITOM } from './service_itom';
|
||||
import * as utils from '../lib/axios_utils';
|
||||
import * as utils from '../../lib/axios_utils';
|
||||
import { ExternalServiceITOM } from './types';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
@ -19,8 +19,8 @@ import { itomEventParams, serviceNowChoices } from './mocks';
|
|||
const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
|
||||
|
||||
jest.mock('axios');
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
jest.mock('../../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { ServiceFactory, ExternalServiceITOM, ExecutorSubActionAddEventParams } from './types';
|
||||
|
||||
import { request } from '../lib/axios_utils';
|
||||
import { request } from '../../lib/axios_utils';
|
||||
import { createExternalService } from './service';
|
||||
import { createServiceError } from './utils';
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import axios from 'axios';
|
||||
|
||||
import { createExternalServiceSIR } from './service_sir';
|
||||
import * as utils from '../lib/axios_utils';
|
||||
import * as utils from '../../lib/axios_utils';
|
||||
import { ExternalServiceSIR } from './types';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
@ -19,8 +19,8 @@ import { snExternalServiceConfig } from './config';
|
|||
const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
|
||||
|
||||
jest.mock('axios');
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
jest.mock('../../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { Observable, ExternalServiceSIR, ObservableResponse, ServiceFactory } from './types';
|
||||
|
||||
import { request } from '../lib/axios_utils';
|
||||
import { request } from '../../lib/axios_utils';
|
||||
import { createExternalService } from './service';
|
||||
import { createServiceError } from './utils';
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
ServiceNowSecretConfigurationType,
|
||||
} from './types';
|
||||
import { FIELD_PREFIX } from './config';
|
||||
import { addTimeZoneToDate, getErrorMessage } from '../lib/axios_utils';
|
||||
import { addTimeZoneToDate, getErrorMessage } from '../../lib/axios_utils';
|
||||
import * as i18n from './translations';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
import { ConnectorTokenClientContract } from '../../types';
|
||||
|
|
|
@ -10,7 +10,7 @@ import axios from 'axios';
|
|||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { actionsConfigMock } from '../../actions_config.mock';
|
||||
import { request, createAxiosResponse } from '../lib/axios_utils';
|
||||
import { request, createAxiosResponse } from '../../lib/axios_utils';
|
||||
import { createExternalService } from './service';
|
||||
import { mappings } from './mocks';
|
||||
import { ExternalService } from './types';
|
||||
|
@ -18,8 +18,8 @@ import { ExternalService } from './types';
|
|||
const logger = loggingSystemMock.create().get() as jest.Mocked<Logger>;
|
||||
|
||||
jest.mock('axios');
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
jest.mock('../../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Logger } from '@kbn/logging';
|
|||
import axios from 'axios';
|
||||
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
import { getErrorMessage, request, throwIfResponseIsNotValid } from '../lib/axios_utils';
|
||||
import { getErrorMessage, request, throwIfResponseIsNotValid } from '../../lib/axios_utils';
|
||||
import { getBodyForEventAction } from './helpers';
|
||||
import {
|
||||
CreateCommentParams,
|
||||
|
|
|
@ -13,12 +13,12 @@ import { ActionParamsType, ActionTypeSecretsType, getActionType, TeamsActionType
|
|||
import { actionsConfigMock } from '../actions_config.mock';
|
||||
import { actionsMock } from '../mocks';
|
||||
import { createActionTypeRegistry } from './index.test';
|
||||
import * as utils from './lib/axios_utils';
|
||||
import * as utils from '../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../actions_config';
|
||||
|
||||
jest.mock('axios');
|
||||
jest.mock('./lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('./lib/axios_utils');
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -15,7 +15,7 @@ import { map, getOrElse } from 'fp-ts/lib/Option';
|
|||
import { Logger } from '@kbn/core/server';
|
||||
import { getRetryAfterIntervalFromHeaders } from './lib/http_rersponse_retry_header';
|
||||
import { isOk, promiseResult, Result } from './lib/result_type';
|
||||
import { request } from './lib/axios_utils';
|
||||
import { request } from '../lib/axios_utils';
|
||||
import {
|
||||
ActionType,
|
||||
ActionTypeExecutorOptions,
|
||||
|
|
|
@ -21,12 +21,12 @@ import {
|
|||
WebhookMethods,
|
||||
} from './webhook';
|
||||
|
||||
import * as utils from './lib/axios_utils';
|
||||
import * as utils from '../lib/axios_utils';
|
||||
import { ActionsConfigurationUtilities } from '../actions_config';
|
||||
|
||||
jest.mock('axios');
|
||||
jest.mock('./lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('./lib/axios_utils');
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
ValidatorServices,
|
||||
} from '../types';
|
||||
import { ActionsConfigurationUtilities } from '../actions_config';
|
||||
import { request } from './lib/axios_utils';
|
||||
import { request } from '../lib/axios_utils';
|
||||
import { renderMustacheString } from '../lib/mustache_renderer';
|
||||
import {
|
||||
AlertingConnectorFeatureId,
|
||||
|
@ -190,7 +190,7 @@ export async function executor(
|
|||
url,
|
||||
logger,
|
||||
...basicAuth,
|
||||
headers,
|
||||
headers: headers ? headers : {},
|
||||
data,
|
||||
configurationUtilities,
|
||||
})
|
||||
|
|
|
@ -17,7 +17,7 @@ import { duration as momentDuration } from 'moment';
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import getPort from 'get-port';
|
||||
|
||||
import { request } from '../builtin_action_types/lib/axios_utils';
|
||||
import { request } from '../lib/axios_utils';
|
||||
import { ByteSizeValue } from '@kbn/config-schema';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
|
|
@ -17,7 +17,7 @@ import { duration as momentDuration } from 'moment';
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import getPort from 'get-port';
|
||||
|
||||
import { request } from '../builtin_action_types/lib/axios_utils';
|
||||
import { request } from '../lib/axios_utils';
|
||||
import { ByteSizeValue } from '@kbn/config-schema';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
|
|
|
@ -19,8 +19,8 @@ import {
|
|||
createAxiosResponse,
|
||||
} from './axios_utils';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
import { actionsConfigMock } from '../../actions_config.mock';
|
||||
import { getCustomAgents } from './get_custom_agents';
|
||||
import { actionsConfigMock } from '../actions_config.mock';
|
||||
import { getCustomAgents } from '../builtin_action_types/lib/get_custom_agents';
|
||||
|
||||
const TestUrl = 'https://elastic.co/foo/bar/baz';
|
||||
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
import { isObjectLike, isEmpty } from 'lodash';
|
||||
import { AxiosInstance, Method, AxiosResponse, AxiosBasicCredentials } from 'axios';
|
||||
import { AxiosInstance, Method, AxiosResponse, AxiosRequestConfig } from 'axios';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { getCustomAgents } from './get_custom_agents';
|
||||
import { ActionsConfigurationUtilities } from '../../actions_config';
|
||||
import { getCustomAgents } from '../builtin_action_types/lib/get_custom_agents';
|
||||
import { ActionsConfigurationUtilities } from '../actions_config';
|
||||
|
||||
export const request = async <T = unknown>({
|
||||
axios,
|
||||
|
@ -19,24 +19,21 @@ export const request = async <T = unknown>({
|
|||
data,
|
||||
configurationUtilities,
|
||||
headers,
|
||||
...rest
|
||||
...config
|
||||
}: {
|
||||
axios: AxiosInstance;
|
||||
url: string;
|
||||
logger: Logger;
|
||||
method?: Method;
|
||||
data?: T;
|
||||
params?: unknown;
|
||||
configurationUtilities: ActionsConfigurationUtilities;
|
||||
headers?: Record<string, string> | null;
|
||||
validateStatus?: (status: number) => boolean;
|
||||
auth?: AxiosBasicCredentials;
|
||||
}): Promise<AxiosResponse> => {
|
||||
} & AxiosRequestConfig): Promise<AxiosResponse> => {
|
||||
const { httpAgent, httpsAgent } = getCustomAgents(configurationUtilities, logger, url);
|
||||
const { maxContentLength, timeout } = configurationUtilities.getResponseSettings();
|
||||
|
||||
return await axios(url, {
|
||||
...rest,
|
||||
...config,
|
||||
method,
|
||||
// Axios doesn't support `null` value for `headers` property.
|
||||
headers: headers ?? undefined,
|
|
@ -5,21 +5,27 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Agent as HttpsAgent } from 'https';
|
||||
import HttpProxyAgent from 'http-proxy-agent';
|
||||
import { HttpsProxyAgent } from 'https-proxy-agent';
|
||||
import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';
|
||||
import { loggingSystemMock } from '@kbn/core/server/mocks';
|
||||
import { MockedLogger } from '@kbn/logging-mocks';
|
||||
import { actionsConfigMock } from '../actions_config.mock';
|
||||
import { actionsMock } from '../mocks';
|
||||
import { TestSubActionConnector } from './mocks';
|
||||
import { getCustomAgents } from '../builtin_action_types/lib/get_custom_agents';
|
||||
import { ActionsConfigurationUtilities } from '../actions_config';
|
||||
import * as utils from '../lib/axios_utils';
|
||||
|
||||
jest.mock('axios');
|
||||
const axiosMock = axios as jest.Mocked<typeof axios>;
|
||||
|
||||
jest.mock('../lib/axios_utils', () => {
|
||||
const originalUtils = jest.requireActual('../lib/axios_utils');
|
||||
return {
|
||||
...originalUtils,
|
||||
request: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
const axiosMock = axios as jest.Mocked<typeof axios>;
|
||||
const requestMock = utils.request as jest.Mock;
|
||||
const createAxiosError = (): AxiosError => {
|
||||
const error = new Error() as AxiosError;
|
||||
error.isAxiosError = true;
|
||||
|
@ -42,7 +48,7 @@ describe('SubActionConnector', () => {
|
|||
jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
|
||||
axiosInstanceMock.mockReturnValue({ data: { status: 'ok' } });
|
||||
requestMock.mockReturnValue({ data: { status: 'ok' } });
|
||||
axiosMock.create.mockImplementation(() => {
|
||||
return axiosInstanceMock as unknown as AxiosInstance;
|
||||
});
|
||||
|
@ -80,12 +86,12 @@ describe('SubActionConnector', () => {
|
|||
describe('URL validation', () => {
|
||||
it('removes double slashes correctly', async () => {
|
||||
await service.testUrl({ url: 'https://example.com//api///test-endpoint' });
|
||||
expect(axiosInstanceMock.mock.calls[0][0]).toBe('https://example.com/api/test-endpoint');
|
||||
expect(requestMock.mock.calls[0][0].url).toBe('https://example.com/api/test-endpoint');
|
||||
});
|
||||
|
||||
it('removes the ending slash correctly', async () => {
|
||||
await service.testUrl({ url: 'https://example.com/' });
|
||||
expect(axiosInstanceMock.mock.calls[0][0]).toBe('https://example.com');
|
||||
expect(requestMock.mock.calls[0][0].url).toBe('https://example.com');
|
||||
});
|
||||
|
||||
it('throws an error if the url is invalid', async () => {
|
||||
|
@ -126,24 +132,24 @@ describe('SubActionConnector', () => {
|
|||
it('sets data to an empty object if the data are null', async () => {
|
||||
await service.testUrl({ url: 'https://example.com', data: null });
|
||||
|
||||
expect(axiosInstanceMock).toHaveBeenCalledTimes(1);
|
||||
const { data } = axiosInstanceMock.mock.calls[0][1];
|
||||
expect(requestMock).toHaveBeenCalledTimes(1);
|
||||
const { data } = requestMock.mock.calls[0][0];
|
||||
expect(data).toEqual({});
|
||||
});
|
||||
|
||||
it('pass data to axios correctly if not null', async () => {
|
||||
await service.testUrl({ url: 'https://example.com', data: { foo: 'foo' } });
|
||||
|
||||
expect(axiosInstanceMock).toHaveBeenCalledTimes(1);
|
||||
const { data } = axiosInstanceMock.mock.calls[0][1];
|
||||
expect(requestMock).toHaveBeenCalledTimes(1);
|
||||
const { data } = requestMock.mock.calls[0][0];
|
||||
expect(data).toEqual({ foo: 'foo' });
|
||||
});
|
||||
|
||||
it('removeNullOrUndefinedFields: removes null values and undefined values correctly', async () => {
|
||||
await service.testData({ data: { foo: 'foo', bar: null, baz: undefined } });
|
||||
|
||||
expect(axiosInstanceMock).toHaveBeenCalledTimes(1);
|
||||
const { data } = axiosInstanceMock.mock.calls[0][1];
|
||||
expect(requestMock).toHaveBeenCalledTimes(1);
|
||||
const { data } = requestMock.mock.calls[0][0];
|
||||
expect(data).toEqual({ foo: 'foo' });
|
||||
});
|
||||
|
||||
|
@ -153,7 +159,7 @@ describe('SubActionConnector', () => {
|
|||
// @ts-expect-error
|
||||
await service.testData({ data: dataToTest });
|
||||
|
||||
const { data } = axiosInstanceMock.mock.calls[0][1];
|
||||
const { data } = requestMock.mock.calls[0][0];
|
||||
expect(data).toEqual({});
|
||||
}
|
||||
);
|
||||
|
@ -163,19 +169,18 @@ describe('SubActionConnector', () => {
|
|||
it('fetch correctly', async () => {
|
||||
const res = await service.testUrl({ url: 'https://example.com' });
|
||||
|
||||
expect(axiosInstanceMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosInstanceMock).toBeCalledWith('https://example.com', {
|
||||
expect(requestMock).toHaveBeenCalledTimes(1);
|
||||
expect(requestMock).toBeCalledWith({
|
||||
axios: axiosInstanceMock,
|
||||
configurationUtilities: mockedActionsConfig,
|
||||
logger,
|
||||
method: 'get',
|
||||
data: {},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Test-Header': 'test',
|
||||
},
|
||||
httpAgent: undefined,
|
||||
httpsAgent: expect.any(HttpsAgent),
|
||||
proxy: false,
|
||||
maxContentLength: 1000000,
|
||||
timeout: 360000,
|
||||
url: 'https://example.com',
|
||||
});
|
||||
|
||||
expect(logger.debug).toBeCalledWith(
|
||||
|
@ -186,14 +191,14 @@ describe('SubActionConnector', () => {
|
|||
});
|
||||
|
||||
it('validates the response correctly', async () => {
|
||||
axiosInstanceMock.mockReturnValue({ data: { invalidField: 'test' } });
|
||||
requestMock.mockReturnValue({ data: { invalidField: 'test' } });
|
||||
await expect(async () => service.testUrl({ url: 'https://example.com' })).rejects.toThrow(
|
||||
'Response validation failed (Error: [status]: expected value of type [string] but got [undefined])'
|
||||
);
|
||||
});
|
||||
|
||||
it('formats the response error correctly', async () => {
|
||||
axiosInstanceMock.mockImplementation(() => {
|
||||
requestMock.mockImplementation(() => {
|
||||
throw createAxiosError();
|
||||
});
|
||||
|
||||
|
@ -206,138 +211,4 @@ describe('SubActionConnector', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Proxy', () => {
|
||||
it('have been called with proper proxy agent for a valid url', async () => {
|
||||
mockedActionsConfig.getProxySettings.mockReturnValue({
|
||||
proxySSLSettings: {
|
||||
verificationMode: 'full',
|
||||
},
|
||||
proxyUrl: 'https://localhost:1212',
|
||||
proxyBypassHosts: undefined,
|
||||
proxyOnlyHosts: undefined,
|
||||
});
|
||||
|
||||
const { httpAgent, httpsAgent } = getCustomAgents(
|
||||
mockedActionsConfig,
|
||||
logger,
|
||||
'https://example.com'
|
||||
);
|
||||
|
||||
await service.testUrl({ url: 'https://example.com' });
|
||||
|
||||
expect(axiosInstanceMock).toBeCalledWith('https://example.com', {
|
||||
method: 'get',
|
||||
data: {},
|
||||
headers: {
|
||||
'X-Test-Header': 'test',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
httpAgent,
|
||||
httpsAgent,
|
||||
proxy: false,
|
||||
maxContentLength: 1000000,
|
||||
timeout: 360000,
|
||||
});
|
||||
});
|
||||
|
||||
it('have been called with proper proxy agent for an invalid url', async () => {
|
||||
mockedActionsConfig.getProxySettings.mockReturnValue({
|
||||
proxyUrl: ':nope:',
|
||||
proxySSLSettings: {
|
||||
verificationMode: 'none',
|
||||
},
|
||||
proxyBypassHosts: undefined,
|
||||
proxyOnlyHosts: undefined,
|
||||
});
|
||||
|
||||
await service.testUrl({ url: 'https://example.com' });
|
||||
|
||||
expect(axiosInstanceMock).toBeCalledWith('https://example.com', {
|
||||
method: 'get',
|
||||
data: {},
|
||||
headers: {
|
||||
'X-Test-Header': 'test',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
httpAgent: undefined,
|
||||
httpsAgent: expect.any(HttpsAgent),
|
||||
proxy: false,
|
||||
maxContentLength: 1000000,
|
||||
timeout: 360000,
|
||||
});
|
||||
});
|
||||
|
||||
it('bypasses with proxyBypassHosts when expected', async () => {
|
||||
mockedActionsConfig.getProxySettings.mockReturnValue({
|
||||
proxySSLSettings: {
|
||||
verificationMode: 'full',
|
||||
},
|
||||
proxyUrl: 'https://elastic.proxy.co',
|
||||
proxyBypassHosts: new Set(['example.com']),
|
||||
proxyOnlyHosts: undefined,
|
||||
});
|
||||
|
||||
await service.testUrl({ url: 'https://example.com' });
|
||||
|
||||
expect(axiosInstanceMock).toHaveBeenCalledTimes(1);
|
||||
const { httpAgent, httpsAgent } = axiosInstanceMock.mock.calls[0][1];
|
||||
expect(httpAgent instanceof HttpProxyAgent).toBe(false);
|
||||
expect(httpsAgent instanceof HttpsProxyAgent).toBe(false);
|
||||
});
|
||||
|
||||
it('does not bypass with proxyBypassHosts when expected', async () => {
|
||||
mockedActionsConfig.getProxySettings.mockReturnValue({
|
||||
proxySSLSettings: {
|
||||
verificationMode: 'full',
|
||||
},
|
||||
proxyUrl: 'https://elastic.proxy.co',
|
||||
proxyBypassHosts: new Set(['not-example.com']),
|
||||
proxyOnlyHosts: undefined,
|
||||
});
|
||||
|
||||
await service.testUrl({ url: 'https://example.com' });
|
||||
|
||||
expect(axiosInstanceMock).toHaveBeenCalledTimes(1);
|
||||
const { httpAgent, httpsAgent } = axiosInstanceMock.mock.calls[0][1];
|
||||
expect(httpAgent instanceof HttpProxyAgent).toBe(true);
|
||||
expect(httpsAgent instanceof HttpsProxyAgent).toBe(true);
|
||||
});
|
||||
|
||||
it('proxies with proxyOnlyHosts when expected', async () => {
|
||||
mockedActionsConfig.getProxySettings.mockReturnValue({
|
||||
proxySSLSettings: {
|
||||
verificationMode: 'full',
|
||||
},
|
||||
proxyUrl: 'https://elastic.proxy.co',
|
||||
proxyBypassHosts: undefined,
|
||||
proxyOnlyHosts: new Set(['example.com']),
|
||||
});
|
||||
|
||||
await service.testUrl({ url: 'https://example.com' });
|
||||
|
||||
expect(axiosInstanceMock).toHaveBeenCalledTimes(1);
|
||||
const { httpAgent, httpsAgent } = axiosInstanceMock.mock.calls[0][1];
|
||||
expect(httpAgent instanceof HttpProxyAgent).toBe(true);
|
||||
expect(httpsAgent instanceof HttpsProxyAgent).toBe(true);
|
||||
});
|
||||
|
||||
it('does not proxy with proxyOnlyHosts when expected', async () => {
|
||||
mockedActionsConfig.getProxySettings.mockReturnValue({
|
||||
proxySSLSettings: {
|
||||
verificationMode: 'full',
|
||||
},
|
||||
proxyUrl: 'https://elastic.proxy.co',
|
||||
proxyBypassHosts: undefined,
|
||||
proxyOnlyHosts: new Set(['not-example.com']),
|
||||
});
|
||||
|
||||
await service.testUrl({ url: 'https://example.com' });
|
||||
|
||||
expect(axiosInstanceMock).toHaveBeenCalledTimes(1);
|
||||
const { httpAgent, httpsAgent } = axiosInstanceMock.mock.calls[0][1];
|
||||
expect(httpAgent instanceof HttpProxyAgent).toBe(false);
|
||||
expect(httpsAgent instanceof HttpsProxyAgent).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,10 +17,10 @@ import axios, {
|
|||
AxiosRequestHeaders,
|
||||
} from 'axios';
|
||||
import { ActionsConfigurationUtilities } from '../actions_config';
|
||||
import { getCustomAgents } from '../builtin_action_types/lib/get_custom_agents';
|
||||
import { SubAction } from './types';
|
||||
import { ServiceParams } from './types';
|
||||
import * as i18n from './translations';
|
||||
import { request } from '../lib/axios_utils';
|
||||
|
||||
const isObject = (value: unknown): value is Record<string, unknown> => {
|
||||
return isPlainObject(value);
|
||||
|
@ -133,27 +133,19 @@ export abstract class SubActionConnector<Config, Secrets> {
|
|||
this.ensureUriAllowed(url);
|
||||
const normalizedURL = this.normalizeURL(url);
|
||||
|
||||
const { httpAgent, httpsAgent } = getCustomAgents(
|
||||
this.configurationUtilities,
|
||||
this.logger,
|
||||
url
|
||||
);
|
||||
const { maxContentLength, timeout } = this.configurationUtilities.getResponseSettings();
|
||||
|
||||
this.logger.debug(
|
||||
`Request to external service. Connector Id: ${this.connector.id}. Connector type: ${this.connector.type} Method: ${method}. URL: ${normalizedURL}`
|
||||
);
|
||||
const res = await this.axiosInstance(normalizedURL, {
|
||||
|
||||
const res = await request({
|
||||
...config,
|
||||
axios: this.axiosInstance,
|
||||
url: normalizedURL,
|
||||
logger: this.logger,
|
||||
method,
|
||||
headers: this.getHeaders(headers),
|
||||
data: this.normalizeData(data),
|
||||
// use httpAgent and httpsAgent and set axios proxy: false, to be able to handle fail on invalid certs
|
||||
httpAgent,
|
||||
httpsAgent,
|
||||
proxy: false,
|
||||
maxContentLength,
|
||||
timeout,
|
||||
configurationUtilities: this.configurationUtilities,
|
||||
headers: this.getHeaders(headers),
|
||||
});
|
||||
|
||||
this.validateResponse(responseSchema, res.data);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue