mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Migrated last pieces of legacy fixture code (#74470)
* Migrated last pieces of legacy fixture code * Implemented own server for webhook simulator * Fixed type checks. Moved slack simulator to own server * close server after tests run * Fixed due to comments * fixed failing tests
This commit is contained in:
parent
5b64a4cdfe
commit
124bd126f8
14 changed files with 269 additions and 282 deletions
|
@ -255,8 +255,8 @@
|
|||
"cronstrue": "^1.51.0",
|
||||
"cytoscape": "^3.10.0",
|
||||
"d3": "3.5.17",
|
||||
"d3-scale": "1.0.7",
|
||||
"d3-array": "1.2.4",
|
||||
"d3-scale": "1.0.7",
|
||||
"dedent": "^0.7.0",
|
||||
"del": "^5.1.0",
|
||||
"dragselect": "1.13.1",
|
||||
|
@ -267,7 +267,7 @@
|
|||
"font-awesome": "4.7.0",
|
||||
"formsy-react": "^1.1.5",
|
||||
"fp-ts": "^2.3.1",
|
||||
"get-port": "4.2.0",
|
||||
"get-port": "^4.2.0",
|
||||
"getos": "^3.1.0",
|
||||
"git-url-parse": "11.1.2",
|
||||
"github-markdown-css": "^2.10.0",
|
||||
|
|
|
@ -4,26 +4,25 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import http from 'http';
|
||||
import getPort from 'get-port';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
|
||||
import {
|
||||
getExternalServiceSimulatorPath,
|
||||
ExternalServiceSimulator,
|
||||
} from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
import { getSlackServer } from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function slackTest({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
describe('slack action', () => {
|
||||
let slackSimulatorURL: string = '<could not determine kibana url>';
|
||||
let slackSimulatorURL: string = '';
|
||||
let slackServer: http.Server;
|
||||
|
||||
// need to wait for kibanaServer to settle ...
|
||||
before(() => {
|
||||
slackSimulatorURL = kibanaServer.resolveUrl(
|
||||
getExternalServiceSimulatorPath(ExternalServiceSimulator.SLACK)
|
||||
);
|
||||
before(async () => {
|
||||
slackServer = await getSlackServer();
|
||||
const availablePort = await getPort({ port: 9000 });
|
||||
slackServer.listen(availablePort);
|
||||
slackSimulatorURL = `http://localhost:${availablePort}`;
|
||||
});
|
||||
|
||||
it('should return 403 when creating a slack action', async () => {
|
||||
|
@ -44,5 +43,9 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
'Action type .slack is disabled because your basic license does not support it. Please upgrade your license.',
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
slackServer.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,25 +4,24 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import http from 'http';
|
||||
import getPort from 'get-port';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
import {
|
||||
getExternalServiceSimulatorPath,
|
||||
ExternalServiceSimulator,
|
||||
} from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
import { getWebhookServer } from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function webhookTest({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
describe('webhook action', () => {
|
||||
let webhookSimulatorURL: string = '<could not determine kibana url>';
|
||||
|
||||
let webhookSimulatorURL: string = '';
|
||||
let webhookServer: http.Server;
|
||||
// need to wait for kibanaServer to settle ...
|
||||
before(() => {
|
||||
webhookSimulatorURL = kibanaServer.resolveUrl(
|
||||
getExternalServiceSimulatorPath(ExternalServiceSimulator.WEBHOOK)
|
||||
);
|
||||
before(async () => {
|
||||
webhookServer = await getWebhookServer();
|
||||
const availablePort = await getPort({ port: 9000 });
|
||||
webhookServer.listen(availablePort);
|
||||
webhookSimulatorURL = `http://localhost:${availablePort}`;
|
||||
});
|
||||
|
||||
it('should return 403 when creating a webhook action', async () => {
|
||||
|
@ -47,5 +46,9 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
'Action type .webhook is disabled because your basic license does not support it. Please upgrade your license.',
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
webhookServer.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import http from 'http';
|
||||
import { Plugin, CoreSetup, IRouter } from 'kibana/server';
|
||||
import { EncryptedSavedObjectsPluginStart } from '../../../../../../../plugins/encrypted_saved_objects/server';
|
||||
import { PluginSetupContract as FeaturesPluginSetup } from '../../../../../../../plugins/features/server';
|
||||
|
@ -13,6 +14,8 @@ import { initPlugin as initPagerduty } from './pagerduty_simulation';
|
|||
import { initPlugin as initServiceNow } from './servicenow_simulation';
|
||||
import { initPlugin as initJira } from './jira_simulation';
|
||||
import { initPlugin as initResilient } from './resilient_simulation';
|
||||
import { initPlugin as initSlack } from './slack_simulation';
|
||||
import { initPlugin as initWebhook } from './webhook_simulation';
|
||||
|
||||
export const NAME = 'actions-FTS-external-service-simulators';
|
||||
|
||||
|
@ -39,6 +42,14 @@ export function getAllExternalServiceSimulatorPaths(): string[] {
|
|||
return allPaths;
|
||||
}
|
||||
|
||||
export async function getWebhookServer(): Promise<http.Server> {
|
||||
return await initWebhook();
|
||||
}
|
||||
|
||||
export async function getSlackServer(): Promise<http.Server> {
|
||||
return await initSlack();
|
||||
}
|
||||
|
||||
interface FixtureSetupDeps {
|
||||
actions: ActionsPluginSetupContract;
|
||||
features: FeaturesPluginSetup;
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 http from 'http';
|
||||
|
||||
export async function initPlugin() {
|
||||
return http.createServer((request, response) => {
|
||||
if (request.method === 'POST') {
|
||||
let data = '';
|
||||
request.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
request.on('end', () => {
|
||||
const body = JSON.parse(data);
|
||||
const text = body && body.text;
|
||||
|
||||
if (text == null) {
|
||||
response.statusCode = 400;
|
||||
response.end('bad request to slack simulator');
|
||||
return;
|
||||
}
|
||||
|
||||
switch (text) {
|
||||
case 'success': {
|
||||
response.statusCode = 200;
|
||||
response.end('ok');
|
||||
return;
|
||||
}
|
||||
case 'no_text':
|
||||
response.statusCode = 400;
|
||||
response.end('no_text');
|
||||
return;
|
||||
|
||||
case 'invalid_payload':
|
||||
response.statusCode = 400;
|
||||
response.end('invalid_payload');
|
||||
return;
|
||||
|
||||
case 'invalid_token':
|
||||
response.statusCode = 403;
|
||||
response.end('invalid_token');
|
||||
return;
|
||||
|
||||
case 'status_500':
|
||||
response.statusCode = 500;
|
||||
response.end('simulated slack 500 response');
|
||||
return;
|
||||
|
||||
case 'rate_limit':
|
||||
const res = {
|
||||
retry_after: 1,
|
||||
ok: false,
|
||||
error: 'rate_limited',
|
||||
};
|
||||
|
||||
response.writeHead(429, { 'Content-Type': 'application/json', 'Retry-After': '1' });
|
||||
response.write(JSON.stringify(res));
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
response.statusCode = 400;
|
||||
response.end('unknown request to slack simulator');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import http from 'http';
|
||||
import { fromNullable, map, filter, getOrElse } from 'fp-ts/lib/Option';
|
||||
import { pipe } from 'fp-ts/lib/pipeable';
|
||||
import { constant } from 'fp-ts/lib/function';
|
||||
|
||||
export async function initPlugin() {
|
||||
return http.createServer((request, response) => {
|
||||
const credentials = pipe(
|
||||
fromNullable(request.headers.authorization),
|
||||
map((authorization) => authorization.split(/\s+/)),
|
||||
filter((parts) => parts.length > 1),
|
||||
map((parts) => Buffer.from(parts[1], 'base64').toString()),
|
||||
filter((credentialsPart) => credentialsPart.indexOf(':') !== -1),
|
||||
map((credentialsPart) => {
|
||||
const [username, password] = credentialsPart.split(':');
|
||||
return { username, password };
|
||||
}),
|
||||
getOrElse(constant({ username: '', password: '' }))
|
||||
);
|
||||
|
||||
if (request.method === 'POST' || request.method === 'PUT') {
|
||||
let data = '';
|
||||
request.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
request.on('end', () => {
|
||||
switch (data) {
|
||||
case 'success':
|
||||
response.statusCode = 200;
|
||||
response.end('OK');
|
||||
return;
|
||||
case 'authenticate':
|
||||
return validateAuthentication(credentials, response);
|
||||
case 'success_post_method':
|
||||
return validateRequestUsesMethod(request.method ?? '', 'post', response);
|
||||
case 'success_put_method':
|
||||
return validateRequestUsesMethod(request.method ?? '', 'put', response);
|
||||
case 'failure':
|
||||
response.statusCode = 500;
|
||||
response.end('Error');
|
||||
return;
|
||||
}
|
||||
response.statusCode = 400;
|
||||
response.end(
|
||||
`unknown request to webhook simulator [${data ? `content: ${data}` : `no content`}]`
|
||||
);
|
||||
return;
|
||||
});
|
||||
} else {
|
||||
request.on('end', () => {
|
||||
response.statusCode = 400;
|
||||
response.end('unknown request to webhook simulator [no content]');
|
||||
return;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function validateAuthentication(credentials: any, res: any) {
|
||||
try {
|
||||
expect(credentials).to.eql({
|
||||
username: 'elastic',
|
||||
password: 'changeme',
|
||||
});
|
||||
res.statusCode = 200;
|
||||
res.end('OK');
|
||||
} catch (ex) {
|
||||
res.statusCode = 403;
|
||||
res.end(`the validateAuthentication operation failed. ${ex.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function validateRequestUsesMethod(requestMethod: string, method: string, res: any) {
|
||||
try {
|
||||
expect(requestMethod.toLowerCase()).to.eql(method);
|
||||
res.statusCode = 200;
|
||||
res.end('OK');
|
||||
} catch (ex) {
|
||||
res.statusCode = 403;
|
||||
res.end(`the validateAuthentication operation failed. ${ex.message}`);
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* 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 Hapi from 'hapi';
|
||||
import {
|
||||
getExternalServiceSimulatorPath,
|
||||
NAME,
|
||||
ExternalServiceSimulator,
|
||||
} from '../actions_simulators/server/plugin';
|
||||
|
||||
import { initPlugin as initWebhook } from './webhook_simulation';
|
||||
import { initPlugin as initSlack } from './slack_simulation';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function (kibana: any) {
|
||||
return new kibana.Plugin({
|
||||
require: ['xpack_main'],
|
||||
name: `${NAME}-legacy`,
|
||||
init: (server: Hapi.Server) => {
|
||||
initWebhook(server, getExternalServiceSimulatorPath(ExternalServiceSimulator.WEBHOOK));
|
||||
initSlack(server, getExternalServiceSimulatorPath(ExternalServiceSimulator.SLACK));
|
||||
},
|
||||
});
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"name": "actions-fixtures-legacy",
|
||||
"version": "0.0.0",
|
||||
"kibana": {
|
||||
"version": "kibana"
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* 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 Joi from 'joi';
|
||||
import Hapi from 'hapi';
|
||||
|
||||
interface SlackRequest extends Hapi.Request {
|
||||
payload: {
|
||||
text: string;
|
||||
};
|
||||
}
|
||||
export function initPlugin(server: Hapi.Server, path: string) {
|
||||
server.route({
|
||||
method: 'POST',
|
||||
path,
|
||||
options: {
|
||||
auth: false,
|
||||
validate: {
|
||||
options: { abortEarly: false },
|
||||
payload: Joi.object().keys({
|
||||
text: Joi.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handler: slackHandler as Hapi.Lifecycle.Method,
|
||||
});
|
||||
}
|
||||
// Slack simulator: create a slack action pointing here, and you can get
|
||||
// different responses based on the message posted. See the README.md for
|
||||
// more info.
|
||||
|
||||
function slackHandler(request: SlackRequest, h: any) {
|
||||
const body = request.payload;
|
||||
const text = body && body.text;
|
||||
|
||||
if (text == null) {
|
||||
return htmlResponse(h, 400, 'bad request to slack simulator');
|
||||
}
|
||||
|
||||
switch (text) {
|
||||
case 'success':
|
||||
return htmlResponse(h, 200, 'ok');
|
||||
|
||||
case 'no_text':
|
||||
return htmlResponse(h, 400, 'no_text');
|
||||
|
||||
case 'invalid_payload':
|
||||
return htmlResponse(h, 400, 'invalid_payload');
|
||||
|
||||
case 'invalid_token':
|
||||
return htmlResponse(h, 403, 'invalid_token');
|
||||
|
||||
case 'status_500':
|
||||
return htmlResponse(h, 500, 'simulated slack 500 response');
|
||||
|
||||
case 'rate_limit':
|
||||
const response = {
|
||||
retry_after: 1,
|
||||
ok: false,
|
||||
error: 'rate_limited',
|
||||
};
|
||||
|
||||
return h.response(response).type('application/json').header('retry-after', '1').code(429);
|
||||
}
|
||||
|
||||
return htmlResponse(h, 400, 'unknown request to slack simulator');
|
||||
}
|
||||
|
||||
function htmlResponse(h: any, code: number, text: string) {
|
||||
return h.response(text).type('text/html').code(code);
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import Joi from 'joi';
|
||||
import Hapi, { Util } from 'hapi';
|
||||
import { fromNullable, map, filter, getOrElse } from 'fp-ts/lib/Option';
|
||||
import { pipe } from 'fp-ts/lib/pipeable';
|
||||
import { constant } from 'fp-ts/lib/function';
|
||||
|
||||
interface WebhookRequest extends Hapi.Request {
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export async function initPlugin(server: Hapi.Server, path: string) {
|
||||
server.auth.scheme('identifyCredentialsIfPresent', function identifyCredentialsIfPresent(
|
||||
s: Hapi.Server,
|
||||
options?: Hapi.ServerAuthSchemeOptions
|
||||
) {
|
||||
const scheme = {
|
||||
async authenticate(request: Hapi.Request, h: Hapi.ResponseToolkit) {
|
||||
const credentials = pipe(
|
||||
fromNullable(request.headers.authorization),
|
||||
map((authorization) => authorization.split(/\s+/)),
|
||||
filter((parts) => parts.length > 1),
|
||||
map((parts) => Buffer.from(parts[1], 'base64').toString()),
|
||||
filter((credentialsPart) => credentialsPart.indexOf(':') !== -1),
|
||||
map((credentialsPart) => {
|
||||
const [username, password] = credentialsPart.split(':');
|
||||
return { username, password };
|
||||
}),
|
||||
getOrElse(constant({ username: '', password: '' }))
|
||||
);
|
||||
|
||||
return h.authenticated({ credentials });
|
||||
},
|
||||
};
|
||||
|
||||
return scheme;
|
||||
});
|
||||
server.auth.strategy('simple', 'identifyCredentialsIfPresent');
|
||||
|
||||
server.route({
|
||||
method: ['POST', 'PUT'],
|
||||
path,
|
||||
options: {
|
||||
auth: 'simple',
|
||||
validate: {
|
||||
options: { abortEarly: false },
|
||||
payload: Joi.string(),
|
||||
},
|
||||
},
|
||||
handler: webhookHandler as Hapi.Lifecycle.Method,
|
||||
});
|
||||
}
|
||||
|
||||
function webhookHandler(request: WebhookRequest, h: any) {
|
||||
const body = request.payload;
|
||||
|
||||
switch (body) {
|
||||
case 'success':
|
||||
return htmlResponse(h, 200, `OK`);
|
||||
case 'authenticate':
|
||||
return validateAuthentication(request, h);
|
||||
case 'success_post_method':
|
||||
return validateRequestUsesMethod(request, h, 'post');
|
||||
case 'success_put_method':
|
||||
return validateRequestUsesMethod(request, h, 'put');
|
||||
case 'failure':
|
||||
return htmlResponse(h, 500, `Error`);
|
||||
}
|
||||
|
||||
return htmlResponse(
|
||||
h,
|
||||
400,
|
||||
`unknown request to webhook simulator [${body ? `content: ${body}` : `no content`}]`
|
||||
);
|
||||
}
|
||||
|
||||
function validateAuthentication(request: WebhookRequest, h: any) {
|
||||
const {
|
||||
auth: { credentials },
|
||||
} = request;
|
||||
try {
|
||||
expect(credentials).to.eql({
|
||||
username: 'elastic',
|
||||
password: 'changeme',
|
||||
});
|
||||
return htmlResponse(h, 200, `OK`);
|
||||
} catch (ex) {
|
||||
return htmlResponse(h, 403, `the validateAuthentication operation failed. ${ex.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function validateRequestUsesMethod(
|
||||
request: WebhookRequest,
|
||||
h: any,
|
||||
method: Util.HTTP_METHODS_PARTIAL
|
||||
) {
|
||||
try {
|
||||
expect(request.method).to.eql(method);
|
||||
return htmlResponse(h, 200, `OK`);
|
||||
} catch (ex) {
|
||||
return htmlResponse(h, 403, `the validateAuthentication operation failed. ${ex.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function htmlResponse(h: any, code: number, text: string) {
|
||||
return h.response(text).type('text/html').code(code);
|
||||
}
|
|
@ -5,28 +5,27 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import http from 'http';
|
||||
import getPort from 'get-port';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
|
||||
import {
|
||||
getExternalServiceSimulatorPath,
|
||||
ExternalServiceSimulator,
|
||||
} from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
import { getSlackServer } from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function slackTest({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
describe('slack action', () => {
|
||||
let simulatedActionId = '';
|
||||
let slackSimulatorURL: string = '<could not determine kibana url>';
|
||||
|
||||
let slackSimulatorURL: string = '';
|
||||
let slackServer: http.Server;
|
||||
// need to wait for kibanaServer to settle ...
|
||||
before(() => {
|
||||
slackSimulatorURL = kibanaServer.resolveUrl(
|
||||
getExternalServiceSimulatorPath(ExternalServiceSimulator.SLACK)
|
||||
);
|
||||
before(async () => {
|
||||
slackServer = await getSlackServer();
|
||||
const availablePort = await getPort({ port: 9000 });
|
||||
slackServer.listen(availablePort);
|
||||
slackSimulatorURL = `http://localhost:${availablePort}`;
|
||||
});
|
||||
|
||||
it('should return 200 when creating a slack action successfully', async () => {
|
||||
|
@ -220,5 +219,9 @@ export default function slackTest({ getService }: FtrProviderContext) {
|
|||
expect(result.message).to.match(/error posting a slack message, retry later/);
|
||||
expect(result.retry).to.equal(true);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
slackServer.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import http from 'http';
|
||||
import getPort from 'get-port';
|
||||
import expect from '@kbn/expect';
|
||||
import { URL, format as formatUrl } from 'url';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
import {
|
||||
getExternalServiceSimulatorPath,
|
||||
ExternalServiceSimulator,
|
||||
getWebhookServer,
|
||||
} from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
|
||||
const defaultValues: Record<string, any> = {
|
||||
|
@ -30,11 +33,13 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
async function createWebhookAction(
|
||||
urlWithCreds: string,
|
||||
config: Record<string, string | Record<string, string>> = {}
|
||||
webhookSimulatorURL: string,
|
||||
config: Record<string, string | Record<string, string>> = {},
|
||||
kibanaUrlWithCreds: string
|
||||
): Promise<string> {
|
||||
const { url: fullUrl, user, password } = extractCredentialsFromUrl(urlWithCreds);
|
||||
const url = config.url && typeof config.url === 'object' ? parsePort(config.url) : fullUrl;
|
||||
const { user, password } = extractCredentialsFromUrl(kibanaUrlWithCreds);
|
||||
const url =
|
||||
config.url && typeof config.url === 'object' ? parsePort(config.url) : webhookSimulatorURL;
|
||||
const composedConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
|
@ -61,11 +66,17 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
}
|
||||
|
||||
describe('webhook action', () => {
|
||||
let webhookSimulatorURL: string = '<could not determine kibana url>';
|
||||
|
||||
let webhookSimulatorURL: string = '';
|
||||
let webhookServer: http.Server;
|
||||
let kibanaURL: string = '<could not determine kibana url>';
|
||||
// need to wait for kibanaServer to settle ...
|
||||
before(() => {
|
||||
webhookSimulatorURL = kibanaServer.resolveUrl(
|
||||
before(async () => {
|
||||
webhookServer = await getWebhookServer();
|
||||
const availablePort = await getPort({ port: 9000 });
|
||||
webhookServer.listen(availablePort);
|
||||
webhookSimulatorURL = `http://localhost:${availablePort}`;
|
||||
|
||||
kibanaURL = kibanaServer.resolveUrl(
|
||||
getExternalServiceSimulatorPath(ExternalServiceSimulator.WEBHOOK)
|
||||
);
|
||||
});
|
||||
|
@ -117,7 +128,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('should send authentication to the webhook target', async () => {
|
||||
const webhookActionId = await createWebhookAction(webhookSimulatorURL);
|
||||
const webhookActionId = await createWebhookAction(webhookSimulatorURL, {}, kibanaURL);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
|
@ -132,7 +143,11 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('should support the POST method against webhook target', async () => {
|
||||
const webhookActionId = await createWebhookAction(webhookSimulatorURL, { method: 'post' });
|
||||
const webhookActionId = await createWebhookAction(
|
||||
webhookSimulatorURL,
|
||||
{ method: 'post' },
|
||||
kibanaURL
|
||||
);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
|
@ -147,7 +162,11 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('should support the PUT method against webhook target', async () => {
|
||||
const webhookActionId = await createWebhookAction(webhookSimulatorURL, { method: 'put' });
|
||||
const webhookActionId = await createWebhookAction(
|
||||
webhookSimulatorURL,
|
||||
{ method: 'put' },
|
||||
kibanaURL
|
||||
);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
|
@ -183,7 +202,11 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('should handle unreachable webhook targets', async () => {
|
||||
const webhookActionId = await createWebhookAction('http://some.non.existent.com/endpoint');
|
||||
const webhookActionId = await createWebhookAction(
|
||||
'http://some.non.existent.com/endpoint',
|
||||
{},
|
||||
kibanaURL
|
||||
);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
|
@ -199,7 +222,7 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('should handle failing webhook targets', async () => {
|
||||
const webhookActionId = await createWebhookAction(webhookSimulatorURL);
|
||||
const webhookActionId = await createWebhookAction(webhookSimulatorURL, {}, kibanaURL);
|
||||
const { body: result } = await supertest
|
||||
.post(`/api/actions/action/${webhookActionId}/_execute`)
|
||||
.set('kbn-xsrf', 'test')
|
||||
|
@ -214,6 +237,10 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
expect(result.message).to.match(/error calling webhook, retry later/);
|
||||
expect(result.serviceMessage).to.eql('[500] Internal Server Error');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
webhookServer.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -4,24 +4,22 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import http from 'http';
|
||||
import getPort from 'get-port';
|
||||
import expect from '@kbn/expect';
|
||||
import { URL, format as formatUrl } from 'url';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
import {
|
||||
getExternalServiceSimulatorPath,
|
||||
ExternalServiceSimulator,
|
||||
} from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
import { getWebhookServer } from '../../../../common/fixtures/plugins/actions_simulators/server/plugin';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function webhookTest({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
async function createWebhookAction(
|
||||
urlWithCreds: string,
|
||||
webhookSimulatorURL: string,
|
||||
config: Record<string, string | Record<string, string>> = {}
|
||||
): Promise<string> {
|
||||
const url = formatUrl(new URL(urlWithCreds), { auth: false });
|
||||
const url = formatUrl(new URL(webhookSimulatorURL), { auth: false });
|
||||
const composedConfig = {
|
||||
headers: {
|
||||
'Content-Type': 'text/plain',
|
||||
|
@ -45,13 +43,13 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
}
|
||||
|
||||
describe('webhook action', () => {
|
||||
let webhookSimulatorURL: string = '<could not determine kibana url>';
|
||||
|
||||
// need to wait for kibanaServer to settle ...
|
||||
before(() => {
|
||||
webhookSimulatorURL = kibanaServer.resolveUrl(
|
||||
getExternalServiceSimulatorPath(ExternalServiceSimulator.WEBHOOK)
|
||||
);
|
||||
let webhookSimulatorURL: string = '';
|
||||
let webhookServer: http.Server;
|
||||
before(async () => {
|
||||
webhookServer = await getWebhookServer();
|
||||
const availablePort = await getPort({ port: 9000 });
|
||||
webhookServer.listen(availablePort);
|
||||
webhookSimulatorURL = `http://localhost:${availablePort}`;
|
||||
});
|
||||
|
||||
it('webhook can be executed without username and password', async () => {
|
||||
|
@ -68,5 +66,9 @@ export default function webhookTest({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(result.status).to.eql('ok');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
webhookServer.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14099,7 +14099,7 @@ get-own-enumerable-property-symbols@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203"
|
||||
integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==
|
||||
|
||||
get-port@4.2.0:
|
||||
get-port@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119"
|
||||
integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue