Skip to content

Commit

Permalink
[Transform] Replace legacy elasticsearch client (#84932) (#85396)
Browse files Browse the repository at this point in the history
* [Transform] replace legacy elasticsearch client

* [Transform] delete custom legacy client definition, update transforms_audit_messages.ts

* [Transform] fix start and stop transform endpoints

* [Transform] fix privileges and stats endpoints

* [Transform] fix forbidden

* [Transform] revert continue statement, add a comment

* [Transform] update privileges.ts using security namespace

* [Transform] fix error wrappers

* [Transform] add functional test for preview error validation

* [Transform] extract error message from the root cause

* [Transform] remove error translation
  • Loading branch information
darnautov committed Dec 9, 2020
1 parent de33718 commit c9f38c7
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 280 deletions.
144 changes: 0 additions & 144 deletions x-pack/plugins/transform/server/client/elasticsearch_transform.ts

This file was deleted.

46 changes: 6 additions & 40 deletions x-pack/plugins/transform/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { i18n } from '@kbn/i18n';
import {
CoreSetup,
ILegacyCustomClusterClient,
Plugin,
ILegacyScopedClusterClient,
Logger,
PluginInitializerContext,
} from 'src/core/server';
import { CoreSetup, Plugin, Logger, PluginInitializerContext } from 'src/core/server';

import { LicenseType } from '../../licensing/common/types';

import { elasticsearchJsPlugin } from './client/elasticsearch_transform';
import { Dependencies } from './types';
import { ApiRoutes } from './routes';
import { License } from './services';

declare module 'kibana/server' {
interface RequestHandlerContext {
transform?: {
dataClient: ILegacyScopedClusterClient;
};
}
}

const basicLicense: LicenseType = 'basic';

const PLUGIN = {
Expand All @@ -39,26 +23,21 @@ const PLUGIN = {
}),
};

async function getCustomEsClient(getStartServices: CoreSetup['getStartServices']) {
const [core] = await getStartServices();
return core.elasticsearch.legacy.createClient('transform', {
plugins: [elasticsearchJsPlugin],
});
}

export class TransformServerPlugin implements Plugin<{}, void, any, any> {
private readonly apiRoutes: ApiRoutes;
private readonly license: License;
private readonly logger: Logger;
private transformESClient?: ILegacyCustomClusterClient;

constructor(initContext: PluginInitializerContext) {
this.logger = initContext.logger.get();
this.apiRoutes = new ApiRoutes();
this.license = new License();
}

setup({ http, getStartServices }: CoreSetup, { licensing, features }: Dependencies): {} {
setup(
{ http, getStartServices, elasticsearch }: CoreSetup,
{ licensing, features }: Dependencies
): {} {
const router = http.createRouter();

this.license.setup(
Expand Down Expand Up @@ -94,23 +73,10 @@ export class TransformServerPlugin implements Plugin<{}, void, any, any> {
license: this.license,
});

// Can access via new platform router's handler function 'context' parameter - context.transform.client
http.registerRouteHandlerContext('transform', async (context, request) => {
this.transformESClient =
this.transformESClient ?? (await getCustomEsClient(getStartServices));
return {
dataClient: this.transformESClient.asScoped(request),
};
});

return {};
}

start() {}

stop() {
if (this.transformESClient) {
this.transformESClient.close();
}
}
stop() {}
}
34 changes: 31 additions & 3 deletions x-pack/plugins/transform/server/routes/api/error_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function fillResultsWithTimeouts({ results, id, items, action }: Params)
}

export function wrapError(error: any): CustomHttpResponseOptions<ResponseError> {
const boom = Boom.isBoom(error) ? error : Boom.boomify(error, { statusCode: error.status });
const boom = Boom.isBoom(error) ? error : Boom.boomify(error, { statusCode: error.statusCode });
return {
body: boom,
headers: boom.output.headers,
Expand Down Expand Up @@ -109,14 +109,16 @@ function extractCausedByChain(
* @return Object Boom error response
*/
export function wrapEsError(err: any, statusCodeToMessageMap: Record<string, any> = {}) {
const { statusCode, response } = err;
const {
meta: { body, statusCode },
} = err;

const {
error: {
root_cause = [], // eslint-disable-line @typescript-eslint/naming-convention
caused_by = {}, // eslint-disable-line @typescript-eslint/naming-convention
} = {},
} = JSON.parse(response);
} = body;

// If no custom message if specified for the error's status code, just
// wrap the error as a Boom error response, include the additional information from ES, and return it
Expand All @@ -130,6 +132,12 @@ export function wrapEsError(err: any, statusCodeToMessageMap: Record<string, any

// @ts-expect-error cause is not defined on payload type
boomError.output.payload.cause = causedByChain.length ? causedByChain : defaultCause;

// Set error message based on the root cause
if (root_cause?.[0]) {
boomError.message = extractErrorMessage(root_cause[0]);
}

return boomError;
}

Expand All @@ -138,3 +146,23 @@ export function wrapEsError(err: any, statusCodeToMessageMap: Record<string, any
const message = statusCodeToMessageMap[statusCode];
return new Boom(message, { statusCode });
}

interface EsError {
type: string;
reason: string;
line?: number;
col?: number;
}

/**
* Returns an error message based on the root cause
*/
function extractErrorMessage({ type, reason, line, col }: EsError): string {
let message = `[${type}] ${reason}`;

if (line !== undefined && col !== undefined) {
message += `, with line=${line} & col=${col}`;
}

return message;
}
13 changes: 6 additions & 7 deletions x-pack/plugins/transform/server/routes/api/privileges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ export function registerPrivilegesRoute({ router, license }: RouteDependencies)
return res.ok({ body: privilegesResult });
}

// Get cluster priviliges
// Get cluster privileges
const {
has_all_requested: hasAllPrivileges,
cluster,
} = await ctx.transform!.dataClient.callAsCurrentUser('transport.request', {
path: '/_security/user/_has_privileges',
body: { has_all_requested: hasAllPrivileges, cluster },
} = await ctx.core.elasticsearch.client.asCurrentUser.security.hasPrivileges({
method: 'POST',
body: {
cluster: APP_CLUSTER_PRIVILEGES,
Expand All @@ -43,8 +41,9 @@ export function registerPrivilegesRoute({ router, license }: RouteDependencies)
privilegesResult.hasAllPrivileges = hasAllPrivileges;

// Get all index privileges the user has
const { indices } = await ctx.transform!.dataClient.callAsCurrentUser('transport.request', {
path: '/_security/user/_privileges',
const {
body: { indices },
} = await ctx.core.elasticsearch.client.asCurrentUser.security.getUserPrivileges({
method: 'GET',
});

Expand Down
Loading

0 comments on commit c9f38c7

Please sign in to comment.