[ML] Transforms: Migrate client plugin to NP. (#59443)

Migrates the client side plugin of transforms to NP.
- Gets rid of the last parts of the shim (http, documentation links)
- Moves the plugin from x-pack/legacy/plugins/transform/public to x-pack/plugins/transform
- Creates a custom mock for appDependencies based on NP services
- Fixes jest tests to get rid of all act() related warnings
This commit is contained in:
Walter Rafelsberger 2020-03-06 17:44:35 +01:00 committed by GitHub
parent 708d92a00e
commit f4f956dfeb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
217 changed files with 456 additions and 650 deletions

View file

@ -0,0 +1,77 @@
/*
* 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 { i18n } from '@kbn/i18n';
import { LICENSE_TYPE_BASIC, LicenseType } from '../../../legacy/common/constants';
export const DEFAULT_REFRESH_INTERVAL_MS = 30000;
export const MINIMUM_REFRESH_INTERVAL_MS = 1000;
export const PROGRESS_REFRESH_INTERVAL_MS = 2000;
export const PLUGIN = {
ID: 'transform',
MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC as LicenseType,
getI18nName: (): string => {
return i18n.translate('xpack.transform.appName', {
defaultMessage: 'Transforms',
});
},
};
export const API_BASE_PATH = '/api/transform/';
// In order to create a transform, the API requires the following privileges:
// - transform_admin (builtin)
// - cluster privileges: manage_transform
// - index privileges:
// - indices: .transform-notifications-*, .data-frame-notifications-*, .transform-notifications-read
// - privileges: view_index_metadata, read
// - transform_user (builtin)
// - cluster privileges: monitor_transform
// - index privileges:
// - indices: .transform-notifications-*, .data-frame-notifications-*, .transform-notifications-read
// - privileges: view_index_metadata, read
// - source index: read, view_index_metadata (can be applied to a pattern e.g. farequote-*)
// - dest index: index, create_index (can be applied to a pattern e.g. df-*)
//
// In the UI additional privileges are required:
// - kibana_admin (builtin)
// - dest index: monitor (applied to df-*)
// - cluster: monitor
//
// Note that users with kibana_admin can see all Kibana index patterns and saved searches
// in the source selection modal when creating a transform, but the wizard will trigger
// error callouts when there are no sufficient privileges to read the actual source indices.
export const APP_CLUSTER_PRIVILEGES = [
'cluster:monitor/transform/get',
'cluster:monitor/transform/stats/get',
'cluster:admin/transform/delete',
'cluster:admin/transform/preview',
'cluster:admin/transform/put',
'cluster:admin/transform/start',
'cluster:admin/transform/start_task',
'cluster:admin/transform/stop',
];
// Equivalent of capabilities.canGetTransform
export const APP_GET_TRANSFORM_CLUSTER_PRIVILEGES = [
'cluster.cluster:monitor/transform/get',
'cluster.cluster:monitor/transform/stats/get',
];
// Equivalent of capabilities.canGetTransform
export const APP_CREATE_TRANSFORM_CLUSTER_PRIVILEGES = [
'cluster.cluster:monitor/transform/get',
'cluster.cluster:monitor/transform/stats/get',
'cluster.cluster:admin/transform/preview',
'cluster.cluster:admin/transform/put',
'cluster.cluster:admin/transform/start',
'cluster.cluster:admin/transform/start_task',
];
export const APP_INDEX_PRIVILEGES = ['monitor'];

View file

@ -0,0 +1,40 @@
/*
* 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.
*/
export interface MissingPrivileges {
[key: string]: string[] | undefined;
}
export interface Privileges {
hasAllPrivileges: boolean;
missingPrivileges: MissingPrivileges;
}
export type TransformId = string;
// reflects https://github.com/elastic/elasticsearch/blob/master/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/dataframe/transforms/DataFrameTransformStats.java#L243
export enum TRANSFORM_STATE {
ABORTING = 'aborting',
FAILED = 'failed',
INDEXING = 'indexing',
STARTED = 'started',
STOPPED = 'stopped',
STOPPING = 'stopping',
}
export interface TransformEndpointRequest {
id: TransformId;
state?: TRANSFORM_STATE;
}
export interface ResultData {
success: boolean;
error?: any;
}
export interface TransformEndpointResult {
[key: string]: ResultData;
}

View file

@ -0,0 +1,21 @@
/*
* 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.
*/
export interface Dictionary<TValue> {
[id: string]: TValue;
}
// converts a dictionary to an array. note this loses the dictionary `key` information.
// however it's able to retain the type information of the dictionary elements.
export function dictionaryToArray<TValue>(dict: Dictionary<TValue>): TValue[] {
return Object.keys(dict).map(key => dict[key]);
}
// A recursive partial type to allow passing nested partial attributes.
// Used for example for the optional `jobConfig.dest.results_field` property.
export type DeepPartial<T> = {
[P in keyof T]?: DeepPartial<T[P]>;
};

View file

@ -0,0 +1,26 @@
/*
* 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.
*/
export interface AuditMessageBase {
message: string;
level: string;
timestamp: number;
node_name: string;
text?: string;
}
export interface AuditMessage {
_index: string;
_type: string;
_id: string;
_score: null | number;
_source: TransformMessage;
sort?: any;
}
export interface TransformMessage extends AuditMessageBase {
transform_id: string;
}

View file

@ -0,0 +1,22 @@
/*
* 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.
*/
// utility functions for handling dates
// @ts-ignore
import { formatDate } from '@elastic/eui/lib/services/format';
export function formatHumanReadableDate(ts: number) {
return formatDate(ts, 'MMMM Do YYYY');
}
export function formatHumanReadableDateTime(ts: number) {
return formatDate(ts, 'MMMM Do YYYY, HH:mm');
}
export function formatHumanReadableDateTimeSeconds(ts: number) {
return formatDate(ts, 'MMMM Do YYYY, HH:mm:ss');
}

View file

@ -0,0 +1,42 @@
/*
* 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.
*/
interface WindowWithTextEncoder extends Window {
TextEncoder: any;
}
const windowWithTextEncoder = window as WindowWithTextEncoder;
function isValidIndexNameLength(indexName: string) {
if (
windowWithTextEncoder.TextEncoder &&
new windowWithTextEncoder.TextEncoder('utf-8').encode(indexName).length > 255
) {
return false;
}
// If TextEncoder is not available just check for string.length
return indexName.length <= 255;
}
// rules taken from
// https://github.com/elastic/elasticsearch/blob/master/docs/reference/indices/create-index.asciidoc
export function isValidIndexName(indexName: string) {
return (
// Lowercase only
indexName === indexName.toLowerCase() &&
// Cannot include \, /, *, ?, ", <, >, |, space character, comma, #, :
/^[^\*\\/\?"<>|\s,#:]+$/.test(indexName) &&
// Cannot start with -, _, +
/^[^-_\+]+$/.test(indexName.charAt(0)) &&
// Cannot be . or ..
indexName !== '.' &&
indexName !== '..' &&
// Cannot be longer than 255 bytes (note it is bytes,
// so multi-byte characters will count towards the 255 limit faster)
isValidIndexNameLength(indexName)
);
}

View file

@ -0,0 +1,15 @@
/*
* 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.
*/
// This is similar to lodash's get() except that it's TypeScript aware and is able to infer return types.
// It splits the attribute key string and uses reduce with an idx check to access nested attributes.
export const getNestedProperty = (
obj: Record<string, any>,
accessor: string,
defaultValue?: any
) => {
return accessor.split('.').reduce((o, i) => o?.[i], obj) || defaultValue;
};