Skip to content

Commit

Permalink
Migrated last pieces of legacy fixture code
Browse files Browse the repository at this point in the history
  • Loading branch information
YulNaumenko committed Aug 6, 2020
1 parent 9ef04e7 commit 9a1f3a5
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 225 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';

Expand Down Expand Up @@ -49,7 +52,9 @@ interface FixtureStartDeps {
}

export class FixturePlugin implements Plugin<void, void, FixtureSetupDeps, FixtureStartDeps> {
public setup(core: CoreSetup<FixtureStartDeps>, { features, actions }: FixtureSetupDeps) {
private webhookHttpServer: http.Server | undefined = undefined;

public async setup(core: CoreSetup<FixtureStartDeps>, { features, actions }: FixtureSetupDeps) {
// this action is specifically NOT enabled in ../../config.ts
const notEnabledActionType: ActionType = {
id: 'test.not-enabled',
Expand Down Expand Up @@ -92,8 +97,18 @@ export class FixturePlugin implements Plugin<void, void, FixtureSetupDeps, Fixtu
initServiceNow(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.SERVICENOW));
initJira(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.JIRA));
initResilient(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.RESILIENT));
initSlack(router, getExternalServiceSimulatorPath(ExternalServiceSimulator.SLACK));
this.webhookHttpServer = await initWebhook();
}

public start() {}
public stop() {}
public start() {
if (this.webhookHttpServer) {
this.webhookHttpServer.listen(8080);
}
}
public stop() {
if (this.webhookHttpServer) {
this.webhookHttpServer.close();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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 { schema } from '@kbn/config-schema';
import {
RequestHandlerContext,
KibanaRequest,
KibanaResponseFactory,
IKibanaResponse,
IRouter,
} from 'kibana/server';

export function initPlugin(router: IRouter, path: string) {
router.post(
{
path,
options: {
authRequired: false,
},
validate: {
body: schema.object({
text: schema.string(),
}),
},
},
// ServiceNow simulator: create a servicenow action pointing here, and you can get
// different responses based on the message posted. See the README.md for
// more info.
async function (
context: RequestHandlerContext,
req: KibanaRequest<any, any, any, any>,
res: KibanaResponseFactory
): Promise<IKibanaResponse<any>> {
const body = req.body;
const text = body && body.text;

if (text == null) {
return res.badRequest({ body: 'bad request to slack simulator' });
}

switch (text) {
case 'success':
return res.ok({ body: 'ok' });

case 'no_text':
return res.badRequest({ body: 'no_text' });

case 'invalid_payload':
return res.badRequest({ body: 'invalid_payload' });

case 'invalid_token':
return res.forbidden({ body: 'invalid_token' });

case 'status_500':
return res.internalError({ body: 'simulated slack 500 response' });

case 'rate_limit':
const response = {
retry_after: 1,
ok: false,
error: 'rate_limited',
};

return res.custom({
body: Buffer.from('ok'),
statusCode: 429,
headers: {
'retry-after': '1',
},
});
}

return res.badRequest({ body: 'unknown request to slack simulator' });
}
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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' || 'PUT') {
const data: unknown[] = [];
request.on('data', (chunk) => {
data.push(chunk);
});
request.on('end', () => {
const body = JSON.parse(data.toString());
switch (body) {
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 [${body ? `content: ${body}` : `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).to.eql(method);
res.statusCode = 200;
res.end('OK');
} catch (ex) {
res.statusCode = 403;
res.end(`the validateAuthentication operation failed. ${ex.message}`);
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 9a1f3a5

Please sign in to comment.