mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[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:
parent
708d92a00e
commit
f4f956dfeb
217 changed files with 456 additions and 650 deletions
77
x-pack/plugins/transform/common/constants.ts
Normal file
77
x-pack/plugins/transform/common/constants.ts
Normal 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'];
|
40
x-pack/plugins/transform/common/index.ts
Normal file
40
x-pack/plugins/transform/common/index.ts
Normal 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;
|
||||
}
|
21
x-pack/plugins/transform/common/types/common.ts
Normal file
21
x-pack/plugins/transform/common/types/common.ts
Normal 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]>;
|
||||
};
|
26
x-pack/plugins/transform/common/types/messages.ts
Normal file
26
x-pack/plugins/transform/common/types/messages.ts
Normal 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;
|
||||
}
|
22
x-pack/plugins/transform/common/utils/date_utils.ts
Normal file
22
x-pack/plugins/transform/common/utils/date_utils.ts
Normal 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');
|
||||
}
|
42
x-pack/plugins/transform/common/utils/es_utils.ts
Normal file
42
x-pack/plugins/transform/common/utils/es_utils.ts
Normal 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)
|
||||
);
|
||||
}
|
15
x-pack/plugins/transform/common/utils/object_utils.ts
Normal file
15
x-pack/plugins/transform/common/utils/object_utils.ts
Normal 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;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue