From ad89b1e67fdb5725644e13eb5f8896222e8cddcb Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Wed, 29 Apr 2020 08:50:54 +0200 Subject: [PATCH 01/26] load react component lazily in so management section (#64285) * load react component lazily in so management section * remove unused imports Co-authored-by: Elastic Machine --- .../management_section/mount_section.tsx | 157 +++--------------- .../saved_objects_edition_page.tsx | 76 +++++++++ .../saved_objects_table_page.tsx | 91 ++++++++++ 3 files changed, 191 insertions(+), 133 deletions(-) create mode 100644 src/plugins/saved_objects_management/public/management_section/saved_objects_edition_page.tsx create mode 100644 src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx diff --git a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx index fe3150fc0bb076..c1daf3445219f9 100644 --- a/src/plugins/saved_objects_management/public/management_section/mount_section.tsx +++ b/src/plugins/saved_objects_management/public/management_section/mount_section.tsx @@ -17,23 +17,15 @@ * under the License. */ -import React, { useEffect } from 'react'; +import React, { lazy, Suspense } from 'react'; import ReactDOM from 'react-dom'; -import { HashRouter, Switch, Route, useParams, useLocation } from 'react-router-dom'; -import { parse } from 'query-string'; -import { get } from 'lodash'; -import { i18n } from '@kbn/i18n'; +import { HashRouter, Switch, Route } from 'react-router-dom'; import { I18nProvider } from '@kbn/i18n/react'; -import { CoreSetup, CoreStart, ChromeBreadcrumb, Capabilities } from 'src/core/public'; +import { EuiLoadingSpinner } from '@elastic/eui'; +import { CoreSetup, Capabilities } from 'src/core/public'; import { ManagementAppMountParams } from '../../../management/public'; -import { DataPublicPluginStart } from '../../../data/public'; import { StartDependencies, SavedObjectsManagementPluginStart } from '../plugin'; -import { - ISavedObjectsManagementServiceRegistry, - SavedObjectsManagementActionServiceStart, -} from '../services'; -import { SavedObjectsTable } from './objects_table'; -import { SavedObjectEdition } from './object_view'; +import { ISavedObjectsManagementServiceRegistry } from '../services'; import { getAllowedTypes } from './../lib'; interface MountParams { @@ -44,6 +36,8 @@ interface MountParams { let allowedObjectTypes: string[] | undefined; +const SavedObjectsEditionPage = lazy(() => import('./saved_objects_edition_page')); +const SavedObjectsTablePage = lazy(() => import('./saved_objects_table_page')); export const mountManagementSection = async ({ core, mountParams, @@ -63,23 +57,27 @@ export const mountManagementSection = async ({ - + }> + + - + }> + + @@ -103,110 +101,3 @@ const RedirectToHomeIfUnauthorized: React.FunctionComponent<{ } return children! as React.ReactElement; }; - -const SavedObjectsEditionPage = ({ - coreStart, - serviceRegistry, - setBreadcrumbs, -}: { - coreStart: CoreStart; - serviceRegistry: ISavedObjectsManagementServiceRegistry; - setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; -}) => { - const { service: serviceName, id } = useParams<{ service: string; id: string }>(); - const capabilities = coreStart.application.capabilities; - - const { search } = useLocation(); - const query = parse(search); - const service = serviceRegistry.get(serviceName); - - useEffect(() => { - setBreadcrumbs([ - { - text: i18n.translate('savedObjectsManagement.breadcrumb.index', { - defaultMessage: 'Saved objects', - }), - href: '#/management/kibana/objects', - }, - { - text: i18n.translate('savedObjectsManagement.breadcrumb.edit', { - defaultMessage: 'Edit {savedObjectType}', - values: { savedObjectType: service?.service.type ?? 'object' }, - }), - }, - ]); - }, [setBreadcrumbs, service]); - - return ( - - ); -}; - -const SavedObjectsTablePage = ({ - coreStart, - dataStart, - allowedTypes, - serviceRegistry, - actionRegistry, - setBreadcrumbs, -}: { - coreStart: CoreStart; - dataStart: DataPublicPluginStart; - allowedTypes: string[]; - serviceRegistry: ISavedObjectsManagementServiceRegistry; - actionRegistry: SavedObjectsManagementActionServiceStart; - setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; -}) => { - const capabilities = coreStart.application.capabilities; - const itemsPerPage = coreStart.uiSettings.get('savedObjects:perPage', 50); - - useEffect(() => { - setBreadcrumbs([ - { - text: i18n.translate('savedObjectsManagement.breadcrumb.index', { - defaultMessage: 'Saved objects', - }), - href: '#/management/kibana/objects', - }, - ]); - }, [setBreadcrumbs]); - - return ( - { - const { editUrl } = savedObject.meta; - if (editUrl) { - // previously, kbnUrl.change(object.meta.editUrl); was used. - // using direct access to location.hash seems the only option for now, - // as using react-router-dom will prefix the url with the router's basename - // which should be ignored there. - window.location.hash = editUrl; - } - }} - canGoInApp={savedObject => { - const { inAppUrl } = savedObject.meta; - return inAppUrl ? get(capabilities, inAppUrl.uiCapabilitiesPath) : false; - }} - /> - ); -}; diff --git a/src/plugins/saved_objects_management/public/management_section/saved_objects_edition_page.tsx b/src/plugins/saved_objects_management/public/management_section/saved_objects_edition_page.tsx new file mode 100644 index 00000000000000..5ac6e8e103c47c --- /dev/null +++ b/src/plugins/saved_objects_management/public/management_section/saved_objects_edition_page.tsx @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useEffect } from 'react'; +import { useParams, useLocation } from 'react-router-dom'; +import { parse } from 'query-string'; +import { i18n } from '@kbn/i18n'; +import { CoreStart, ChromeBreadcrumb } from 'src/core/public'; +import { ISavedObjectsManagementServiceRegistry } from '../services'; +import { SavedObjectEdition } from './object_view'; + +const SavedObjectsEditionPage = ({ + coreStart, + serviceRegistry, + setBreadcrumbs, +}: { + coreStart: CoreStart; + serviceRegistry: ISavedObjectsManagementServiceRegistry; + setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; +}) => { + const { service: serviceName, id } = useParams<{ service: string; id: string }>(); + const capabilities = coreStart.application.capabilities; + + const { search } = useLocation(); + const query = parse(search); + const service = serviceRegistry.get(serviceName); + + useEffect(() => { + setBreadcrumbs([ + { + text: i18n.translate('savedObjectsManagement.breadcrumb.index', { + defaultMessage: 'Saved objects', + }), + href: '#/management/kibana/objects', + }, + { + text: i18n.translate('savedObjectsManagement.breadcrumb.edit', { + defaultMessage: 'Edit {savedObjectType}', + values: { savedObjectType: service?.service.type ?? 'object' }, + }), + }, + ]); + }, [setBreadcrumbs, service]); + + return ( + + ); +}; + +// eslint-disable-next-line import/no-default-export +export { SavedObjectsEditionPage as default }; diff --git a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx new file mode 100644 index 00000000000000..7660d17f91c5bb --- /dev/null +++ b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx @@ -0,0 +1,91 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { useEffect } from 'react'; +import { get } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { CoreStart, ChromeBreadcrumb } from 'src/core/public'; +import { DataPublicPluginStart } from '../../../data/public'; +import { + ISavedObjectsManagementServiceRegistry, + SavedObjectsManagementActionServiceStart, +} from '../services'; +import { SavedObjectsTable } from './objects_table'; + +const SavedObjectsTablePage = ({ + coreStart, + dataStart, + allowedTypes, + serviceRegistry, + actionRegistry, + setBreadcrumbs, +}: { + coreStart: CoreStart; + dataStart: DataPublicPluginStart; + allowedTypes: string[]; + serviceRegistry: ISavedObjectsManagementServiceRegistry; + actionRegistry: SavedObjectsManagementActionServiceStart; + setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; +}) => { + const capabilities = coreStart.application.capabilities; + const itemsPerPage = coreStart.uiSettings.get('savedObjects:perPage', 50); + + useEffect(() => { + setBreadcrumbs([ + { + text: i18n.translate('savedObjectsManagement.breadcrumb.index', { + defaultMessage: 'Saved objects', + }), + href: '#/management/kibana/objects', + }, + ]); + }, [setBreadcrumbs]); + + return ( + { + const { editUrl } = savedObject.meta; + if (editUrl) { + // previously, kbnUrl.change(object.meta.editUrl); was used. + // using direct access to location.hash seems the only option for now, + // as using react-router-dom will prefix the url with the router's basename + // which should be ignored there. + window.location.hash = editUrl; + } + }} + canGoInApp={savedObject => { + const { inAppUrl } = savedObject.meta; + return inAppUrl ? get(capabilities, inAppUrl.uiCapabilitiesPath) : false; + }} + /> + ); +}; +// eslint-disable-next-line import/no-default-export +export { SavedObjectsTablePage as default }; From a42c2026e23ebeea832b8d0d2b14c0ec7c2f2a5b Mon Sep 17 00:00:00 2001 From: Angela Chuang <6295984+angorayc@users.noreply.github.com> Date: Wed, 29 Apr 2020 09:39:12 +0100 Subject: [PATCH 02/26] [SIEM] Create template timeline (#63136) * init routes for template timeline * create template timeline * add create/update timelines route * update api entry point * fix types * add template type * fix types * add types and template timeline id * fix types * update import timeline to handle template timeline * unit test * sudo code * remove class for savedobject * add template timeline version * clean up arguments * fix types for framework request * show filter in find * fix create template timeline * update mock data * handle missing timeline when exporting * update the order for timeline routes * update schemas * move type to common folder so we can re-use them on UI and server side * fix types + integrate persist with epic timeline * update all timeline when persit timeline * add timeline api readme * fix validation error * fix unit test * display error if unexpected format is given * fix issue with reftech all timeline query * fix flashing timeline while refetch * fix types * fix types * fix dependency * fix timeline deletion * remove redundant dependency * add i18n message * fix unit test Co-authored-by: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Co-authored-by: Elastic Machine --- .../types/timeline/index.ts} | 49 +- .../types/timeline/note/index.ts} | 8 +- .../types/timeline/pinned_event/index.ts} | 14 +- x-pack/plugins/siem/common/utility_types.ts | 4 + .../__snapshots__/index.test.tsx.snap | 4 +- .../open_timeline/export_timeline/index.tsx | 2 +- .../components/open_timeline/index.test.tsx | 27 +- .../public/components/open_timeline/index.tsx | 221 ++++----- .../open_timeline/open_timeline.tsx | 2 +- .../open_timeline_modal/index.test.tsx | 20 + .../public/components/open_timeline/types.ts | 3 + .../components/recent_timelines/index.tsx | 56 ++- .../timeline/selectable_timeline/index.tsx | 110 +++-- .../public/containers/timeline/all/api.ts | 48 -- .../timeline/all/index.gql_query.ts | 3 + .../public/containers/timeline/all/index.tsx | 173 +++++-- .../siem/public/containers/timeline/api.ts | 115 +++++ .../siem/public/graphql/introspection.json | 75 +++ x-pack/plugins/siem/public/graphql/types.ts | 23 + .../siem/public/mock/timeline_results.ts | 39 ++ .../public/pages/timelines/translations.ts | 7 + x-pack/plugins/siem/public/store/store.ts | 1 + .../siem/public/store/timeline/epic.ts | 87 ++-- .../public/store/timeline/epic_favorite.ts | 12 +- .../siem/public/store/timeline/epic_note.ts | 12 +- .../store/timeline/epic_pinned_event.ts | 13 +- .../server/graphql/timeline/schema.gql.ts | 11 + x-pack/plugins/siem/server/graphql/types.ts | 38 ++ .../plugins/siem/server/lib/compose/kibana.ts | 10 +- .../siem/server/lib/note/saved_object.ts | 311 ++++++------ .../server/lib/pinned_event/saved_object.ts | 314 +++++++----- .../convert_saved_object_to_savedtimeline.ts | 17 +- .../create_timelines_stream_from_ndjson.ts | 8 +- .../lib/timeline/pick_saved_timeline.ts | 19 +- .../siem/server/lib/timeline/routes/README.md | 326 +++++++++++++ .../routes/__mocks__/import_timelines.ts | 8 + .../routes/__mocks__/request_responses.ts | 104 +++- .../routes/create_timelines_route.test.ts | 272 +++++++++++ .../timeline/routes/create_timelines_route.ts | 90 ++++ .../routes/import_timelines_route.test.ts | 85 +--- .../timeline/routes/import_timelines_route.ts | 65 +-- .../routes/schemas/create_timelines_schema.ts | 19 + .../routes/schemas/import_timelines_schema.ts | 9 +- .../lib/timeline/routes/schemas/schemas.ts | 10 +- .../routes/schemas/update_timelines_schema.ts | 16 + .../routes/update_timelines_route.test.ts | 288 +++++++++++ .../timeline/routes/update_timelines_route.ts | 87 ++++ .../lib/timeline/routes/utils/common.ts | 30 ++ .../timeline/routes/utils/create_timelines.ts | 150 ++++++ .../timeline/routes/utils/export_timelines.ts | 51 +- .../timeline/routes/utils/import_timelines.ts | 118 +---- .../timeline/routes/utils/update_timelines.ts | 81 ++++ .../siem/server/lib/timeline/saved_object.ts | 458 ++++++++++-------- .../lib/timeline/saved_object_mappings.ts | 9 + x-pack/plugins/siem/server/routes/index.ts | 4 + .../siem/server/utils/typed_resolvers.ts | 4 - 56 files changed, 3040 insertions(+), 1100 deletions(-) rename x-pack/plugins/siem/{server/lib/timeline/types.ts => common/types/timeline/index.ts} (85%) rename x-pack/plugins/siem/{server/lib/note/types.ts => common/types/timeline/note/index.ts} (90%) rename x-pack/plugins/siem/{server/lib/pinned_event/types.ts => common/types/timeline/pinned_event/index.ts} (83%) delete mode 100644 x-pack/plugins/siem/public/containers/timeline/all/api.ts create mode 100644 x-pack/plugins/siem/public/containers/timeline/api.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/README.md create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/create_timelines_route.test.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/create_timelines_route.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/schemas/create_timelines_schema.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/schemas/update_timelines_schema.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/update_timelines_route.test.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/update_timelines_route.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/utils/common.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/utils/create_timelines.ts create mode 100644 x-pack/plugins/siem/server/lib/timeline/routes/utils/update_timelines.ts diff --git a/x-pack/plugins/siem/server/lib/timeline/types.ts b/x-pack/plugins/siem/common/types/timeline/index.ts similarity index 85% rename from x-pack/plugins/siem/server/lib/timeline/types.ts rename to x-pack/plugins/siem/common/types/timeline/index.ts index 0bce3300591c2d..55b4f9c6aca4dc 100644 --- a/x-pack/plugins/siem/server/lib/timeline/types.ts +++ b/x-pack/plugins/siem/common/types/timeline/index.ts @@ -7,14 +7,11 @@ /* eslint-disable @typescript-eslint/no-empty-interface */ import * as runtimeTypes from 'io-ts'; +import { SavedObjectsClient } from 'kibana/server'; -import { unionWithNullType } from '../framework'; -import { NoteSavedObjectToReturnRuntimeType, NoteSavedObject } from '../note/types'; -import { - PinnedEventToReturnSavedObjectRuntimeType, - PinnedEventSavedObject, -} from '../pinned_event/types'; -import { SavedObjectsClient } from '../../../../../../src/core/server'; +import { unionWithNullType } from '../../utility_types'; +import { NoteSavedObject, NoteSavedObjectToReturnRuntimeType } from './note'; +import { PinnedEventToReturnSavedObjectRuntimeType, PinnedEventSavedObject } from './pinned_event'; /* * ColumnHeader Types @@ -136,6 +133,17 @@ const SavedSortRuntimeType = runtimeTypes.partial({ /* * Timeline Types */ + +export enum TimelineType { + default = 'default', + template = 'template', +} + +export const TimelineTypeLiteralRt = runtimeTypes.union([ + runtimeTypes.literal(TimelineType.template), + runtimeTypes.literal(TimelineType.default), +]); + export const SavedTimelineRuntimeType = runtimeTypes.partial({ columns: unionWithNullType(runtimeTypes.array(SavedColumnHeaderRuntimeType)), dataProviders: unionWithNullType(runtimeTypes.array(SavedDataProviderRuntimeType)), @@ -146,6 +154,9 @@ export const SavedTimelineRuntimeType = runtimeTypes.partial({ kqlMode: unionWithNullType(runtimeTypes.string), kqlQuery: unionWithNullType(SavedFilterQueryQueryRuntimeType), title: unionWithNullType(runtimeTypes.string), + templateTimelineId: unionWithNullType(runtimeTypes.string), + templateTimelineVersion: unionWithNullType(runtimeTypes.number), + timelineType: unionWithNullType(TimelineTypeLiteralRt), dateRange: unionWithNullType(SavedDateRangePickerRuntimeType), savedQueryId: unionWithNullType(runtimeTypes.string), sort: unionWithNullType(SavedSortRuntimeType), @@ -192,6 +203,25 @@ export const TimelineSavedToReturnObjectRuntimeType = runtimeTypes.intersection( export interface TimelineSavedObject extends runtimeTypes.TypeOf {} +/** + * All Timeline Saved object type with metadata + */ +export const TimelineResponseType = runtimeTypes.type({ + data: runtimeTypes.type({ + persistTimeline: runtimeTypes.intersection([ + runtimeTypes.partial({ + code: unionWithNullType(runtimeTypes.number), + message: unionWithNullType(runtimeTypes.string), + }), + runtimeTypes.type({ + timeline: TimelineSavedToReturnObjectRuntimeType, + }), + ]), + }), +}); + +export interface TimelineResponse extends runtimeTypes.TypeOf {} + /** * All Timeline Saved object type with metadata */ @@ -234,6 +264,11 @@ export type ExportedTimelines = TimelineSavedObject & pinnedEventIds: string[]; }; +export interface ExportTimelineNotFoundError { + statusCode: number; + message: string; +} + export interface BulkGetInput { type: string; id: string; diff --git a/x-pack/plugins/siem/server/lib/note/types.ts b/x-pack/plugins/siem/common/types/timeline/note/index.ts similarity index 90% rename from x-pack/plugins/siem/server/lib/note/types.ts rename to x-pack/plugins/siem/common/types/timeline/note/index.ts index f7a10317bd84d0..c8e674997c19c1 100644 --- a/x-pack/plugins/siem/server/lib/note/types.ts +++ b/x-pack/plugins/siem/common/types/timeline/note/index.ts @@ -8,7 +8,7 @@ import * as runtimeTypes from 'io-ts'; -import { unionWithNullType } from '../framework'; +import { unionWithNullType } from '../../../utility_types'; /* * Note Types @@ -56,11 +56,7 @@ export const NoteSavedObjectToReturnRuntimeType = runtimeTypes.intersection([ version: runtimeTypes.string, }), runtimeTypes.partial({ - timelineVersion: runtimeTypes.union([ - runtimeTypes.string, - runtimeTypes.null, - runtimeTypes.undefined, - ]), + timelineVersion: unionWithNullType(runtimeTypes.string), }), ]); diff --git a/x-pack/plugins/siem/server/lib/pinned_event/types.ts b/x-pack/plugins/siem/common/types/timeline/pinned_event/index.ts similarity index 83% rename from x-pack/plugins/siem/server/lib/pinned_event/types.ts rename to x-pack/plugins/siem/common/types/timeline/pinned_event/index.ts index e598f039350470..89a619598f7c19 100644 --- a/x-pack/plugins/siem/server/lib/pinned_event/types.ts +++ b/x-pack/plugins/siem/common/types/timeline/pinned_event/index.ts @@ -8,7 +8,7 @@ import * as runtimeTypes from 'io-ts'; -import { unionWithNullType } from '../framework'; +import { unionWithNullType } from '../../../utility_types'; /* * Note Types @@ -40,11 +40,7 @@ export const PinnedEventSavedObjectRuntimeType = runtimeTypes.intersection([ }), runtimeTypes.partial({ pinnedEventId: unionWithNullType(runtimeTypes.string), - timelineVersion: runtimeTypes.union([ - runtimeTypes.string, - runtimeTypes.null, - runtimeTypes.undefined, - ]), + timelineVersion: unionWithNullType(runtimeTypes.string), }), ]); @@ -55,11 +51,7 @@ export const PinnedEventToReturnSavedObjectRuntimeType = runtimeTypes.intersecti }), SavedPinnedEventRuntimeType, runtimeTypes.partial({ - timelineVersion: runtimeTypes.union([ - runtimeTypes.string, - runtimeTypes.null, - runtimeTypes.undefined, - ]), + timelineVersion: unionWithNullType(runtimeTypes.string), }), ]); diff --git a/x-pack/plugins/siem/common/utility_types.ts b/x-pack/plugins/siem/common/utility_types.ts index b46ccdbbe3d05a..a12dd926a91810 100644 --- a/x-pack/plugins/siem/common/utility_types.ts +++ b/x-pack/plugins/siem/common/utility_types.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import * as runtimeTypes from 'io-ts'; import { ReactNode } from 'react'; // This type is for typing EuiDescriptionList @@ -11,3 +12,6 @@ export interface DescriptionList { title: NonNullable; description: NonNullable; } + +export const unionWithNullType = (type: T) => + runtimeTypes.union([type, runtimeTypes.null]); diff --git a/x-pack/plugins/siem/public/components/matrix_histogram/__snapshots__/index.test.tsx.snap b/x-pack/plugins/siem/public/components/matrix_histogram/__snapshots__/index.test.tsx.snap index 5aa846d15b684b..c4bdff7ea649a7 100644 --- a/x-pack/plugins/siem/public/components/matrix_histogram/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/siem/public/components/matrix_histogram/__snapshots__/index.test.tsx.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Matrix Histogram Component not initial load it renders no MatrixLoader 1`] = `"
"`; +exports[`Matrix Histogram Component not initial load it renders no MatrixLoader 1`] = `"
"`; -exports[`Matrix Histogram Component on initial load it renders MatrixLoader 1`] = `"
"`; +exports[`Matrix Histogram Component on initial load it renders MatrixLoader 1`] = `"
"`; diff --git a/x-pack/plugins/siem/public/components/open_timeline/export_timeline/index.tsx b/x-pack/plugins/siem/public/components/open_timeline/export_timeline/index.tsx index 946c4b3a612dd1..12cf952bb1ff86 100644 --- a/x-pack/plugins/siem/public/components/open_timeline/export_timeline/index.tsx +++ b/x-pack/plugins/siem/public/components/open_timeline/export_timeline/index.tsx @@ -9,7 +9,7 @@ import { DeleteTimelines } from '../types'; import { TimelineDownloader } from './export_timeline'; import { DeleteTimelineModalOverlay } from '../delete_timeline_modal'; -import { exportSelectedTimeline } from '../../../containers/timeline/all/api'; +import { exportSelectedTimeline } from '../../../containers/timeline/api'; export interface ExportTimeline { disableExportTimelineDownloader: () => void; diff --git a/x-pack/plugins/siem/public/components/open_timeline/index.test.tsx b/x-pack/plugins/siem/public/components/open_timeline/index.test.tsx index 04f0abe0d00d17..ea28bc06ef915b 100644 --- a/x-pack/plugins/siem/public/components/open_timeline/index.test.tsx +++ b/x-pack/plugins/siem/public/components/open_timeline/index.test.tsx @@ -15,15 +15,34 @@ import { TestProviderWithoutDragAndDrop, apolloClient } from '../../mock/test_pr import { mockOpenTimelineQueryResults } from '../../mock/timeline_results'; import { DEFAULT_SEARCH_RESULTS_PER_PAGE } from '../../pages/timelines/timelines_page'; -import { StatefulOpenTimeline } from '.'; import { NotePreviews } from './note_previews'; import { OPEN_TIMELINE_CLASS_NAME } from './helpers'; - +import { StatefulOpenTimeline } from '.'; +import { useGetAllTimeline, getAllTimeline } from '../../containers/timeline/all'; jest.mock('../../lib/kibana'); +jest.mock('../../containers/timeline/all', () => { + const originalModule = jest.requireActual('../../containers/timeline/all'); + return { + useGetAllTimeline: jest.fn(), + getAllTimeline: originalModule.getAllTimeline, + }; +}); describe('StatefulOpenTimeline', () => { const theme = () => ({ eui: euiDarkVars, darkMode: true }); const title = 'All Timelines / Open Timelines'; + beforeEach(() => { + ((useGetAllTimeline as unknown) as jest.Mock).mockReturnValue({ + fetchAllTimeline: jest.fn(), + timelines: getAllTimeline( + '', + mockOpenTimelineQueryResults[0].result.data?.getAllTimeline?.timeline ?? [] + ), + loading: false, + totalCount: mockOpenTimelineQueryResults[0].result.data.getAllTimeline.totalCount, + refetch: jest.fn(), + }); + }); test('it has the expected initial state', () => { const wrapper = mount( @@ -459,6 +478,8 @@ describe('StatefulOpenTimeline', () => { .find('[data-test-subj="expand-notes"]') .first() .simulate('click'); + expect(wrapper.find('[data-test-subj="note-previews-container"]').exists()).toEqual(true); + expect(wrapper.find('[data-test-subj="updated-by"]').exists()).toEqual(true); expect( wrapper @@ -532,7 +553,7 @@ describe('StatefulOpenTimeline', () => { test('it renders the expected count of matching timelines when no query has been entered', async () => { const wrapper = mount( - + ( /** The requested field to sort on */ const [sortField, setSortField] = useState(DEFAULT_SORT_FIELD); + const { fetchAllTimeline, timelines, loading, totalCount, refetch } = useGetAllTimeline(); + /** Invoked when the user presses enters to submit the text in the search input */ const onQueryChange: OnQueryChange = useCallback((query: EuiSearchBarQuery) => { setSearch(query.queryText.trim()); @@ -133,45 +134,41 @@ export const StatefulOpenTimelineComponent = React.memo( // } // }; - const onDeleteOneTimeline: OnDeleteOneTimeline = useCallback( - (timelineIds: string[]) => { - deleteTimelines(timelineIds, { - search, - pageInfo: { - pageIndex: pageIndex + 1, - pageSize, - }, - sort: { - sortField: sortField as SortFieldTimeline, - sortOrder: sortDirection as Direction, - }, - onlyUserFavorite: onlyFavorites, + const deleteTimelines: DeleteTimelines = useCallback( + async (timelineIds: string[]) => { + if (timelineIds.includes(timeline.savedObjectId || '')) { + createNewTimeline({ id: 'timeline-1', columns: defaultHeaders, show: false }); + } + await apolloClient.mutate< + DeleteTimelineMutation.Mutation, + DeleteTimelineMutation.Variables + >({ + mutation: deleteTimelineMutation, + fetchPolicy: 'no-cache', + variables: { id: timelineIds }, }); + refetch(); + }, + [apolloClient, createNewTimeline, refetch, timeline] + ); + + const onDeleteOneTimeline: OnDeleteOneTimeline = useCallback( + async (timelineIds: string[]) => { + await deleteTimelines(timelineIds); }, - [search, pageIndex, pageSize, sortField, sortDirection, onlyFavorites] + [deleteTimelines] ); /** Invoked when the user clicks the action to delete the selected timelines */ - const onDeleteSelected: OnDeleteSelected = useCallback(() => { - deleteTimelines(getSelectedTimelineIds(selectedItems), { - search, - pageInfo: { - pageIndex: pageIndex + 1, - pageSize, - }, - sort: { - sortField: sortField as SortFieldTimeline, - sortOrder: sortDirection as Direction, - }, - onlyUserFavorite: onlyFavorites, - }); + const onDeleteSelected: OnDeleteSelected = useCallback(async () => { + await deleteTimelines(getSelectedTimelineIds(selectedItems)); // NOTE: we clear the selection state below, but if the server fails to // delete a timeline, it will remain selected in the table: resetSelectionState(); // TODO: the query must re-execute to show the results of the deletion - }, [selectedItems, search, pageIndex, pageSize, sortField, sortDirection, onlyFavorites]); + }, [selectedItems, deleteTimelines]); /** Invoked when the user selects (or de-selects) timelines */ const onSelectionChange: OnSelectionChange = useCallback( @@ -227,99 +224,88 @@ export const StatefulOpenTimelineComponent = React.memo( [apolloClient, updateIsLoading, updateTimeline] ); - const deleteTimelines: DeleteTimelines = useCallback( - (timelineIds: string[], variables?: AllTimelinesVariables) => { - if (timelineIds.includes(timeline.savedObjectId || '')) { - createNewTimeline({ id: 'timeline-1', columns: defaultHeaders, show: false }); - } - apolloClient.mutate({ - mutation: deleteTimelineMutation, - fetchPolicy: 'no-cache', - variables: { id: timelineIds }, - refetchQueries: [ - { - query: allTimelinesQuery, - variables, - }, - ], - }); - }, - [apolloClient, createNewTimeline, timeline] - ); - useEffect(() => { focusInput(); }, []); - return ( - { + fetchAllTimeline({ + pageInfo: { pageIndex: pageIndex + 1, pageSize, - }} - search={search} - sort={{ sortField: sortField as SortFieldTimeline, sortOrder: sortDirection as Direction }} - onlyUserFavorite={onlyFavorites} - > - {({ timelines, loading, totalCount, refetch }) => { - return !isModal ? ( - - ) : ( - - ); - }} - + }, + search, + sort: { sortField: sortField as SortFieldTimeline, sortOrder: sortDirection as Direction }, + onlyUserFavorite: onlyFavorites, + timelines, + totalCount, + }); + }, [ + pageIndex, + pageSize, + search, + sortField, + sortDirection, + timelines, + totalCount, + onlyFavorites, + ]); + + return !isModal ? ( + + ) : ( + ); } ); @@ -328,7 +314,6 @@ const makeMapStateToProps = () => { const getTimeline = timelineSelectors.getTimelineByIdSelector(); const mapStateToProps = (state: State) => { const timeline = getTimeline(state, 'timeline-1') ?? timelineDefaults; - return { timeline, }; diff --git a/x-pack/plugins/siem/public/components/open_timeline/open_timeline.tsx b/x-pack/plugins/siem/public/components/open_timeline/open_timeline.tsx index 6b2f953b82de42..26aeab87e3510c 100644 --- a/x-pack/plugins/siem/public/components/open_timeline/open_timeline.tsx +++ b/x-pack/plugins/siem/public/components/open_timeline/open_timeline.tsx @@ -14,7 +14,7 @@ import { TimelinesTable } from './timelines_table'; import { TitleRow } from './title_row'; import { ImportDataModal } from '../import_data_modal'; import * as i18n from './translations'; -import { importTimelines } from '../../containers/timeline/all/api'; +import { importTimelines } from '../../containers/timeline/api'; import { UtilityBarGroup, diff --git a/x-pack/plugins/siem/public/components/open_timeline/open_timeline_modal/index.test.tsx b/x-pack/plugins/siem/public/components/open_timeline/open_timeline_modal/index.test.tsx index ca8fa50c572fe3..46a0d46c1e0d16 100644 --- a/x-pack/plugins/siem/public/components/open_timeline/open_timeline_modal/index.test.tsx +++ b/x-pack/plugins/siem/public/components/open_timeline/open_timeline_modal/index.test.tsx @@ -13,6 +13,7 @@ import { ThemeProvider } from 'styled-components'; import { wait } from '../../../lib/helpers'; import { TestProviderWithoutDragAndDrop } from '../../../mock/test_providers'; import { mockOpenTimelineQueryResults } from '../../../mock/timeline_results'; +import { useGetAllTimeline, getAllTimeline } from '../../../containers/timeline/all'; import { OpenTimelineModal } from '.'; @@ -20,9 +21,28 @@ jest.mock('../../../lib/kibana'); jest.mock('../../../utils/apollo_context', () => ({ useApolloClient: () => ({}), })); +jest.mock('../../../containers/timeline/all', () => { + const originalModule = jest.requireActual('../../../containers/timeline/all'); + return { + useGetAllTimeline: jest.fn(), + getAllTimeline: originalModule.getAllTimeline, + }; +}); describe('OpenTimelineModal', () => { const theme = () => ({ eui: euiDarkVars, darkMode: true }); + beforeEach(() => { + ((useGetAllTimeline as unknown) as jest.Mock).mockReturnValue({ + fetchAllTimeline: jest.fn(), + timelines: getAllTimeline( + '', + mockOpenTimelineQueryResults[0].result.data?.getAllTimeline?.timeline ?? [] + ), + loading: false, + totalCount: mockOpenTimelineQueryResults[0].result.data.getAllTimeline.totalCount, + refetch: jest.fn(), + }); + }); test('it renders the expected modal', async () => { const wrapper = mount( diff --git a/x-pack/plugins/siem/public/components/open_timeline/types.ts b/x-pack/plugins/siem/public/components/open_timeline/types.ts index b7cc92ebd183f1..41999c62492776 100644 --- a/x-pack/plugins/siem/public/components/open_timeline/types.ts +++ b/x-pack/plugins/siem/public/components/open_timeline/types.ts @@ -9,6 +9,7 @@ import { AllTimelinesVariables } from '../../containers/timeline/all'; import { TimelineModel } from '../../store/timeline/model'; import { NoteResult } from '../../graphql/types'; import { Refetch } from '../../store/inputs/model'; +import { TimelineType } from '../../../common/types/timeline'; /** The users who added a timeline to favorites */ export interface FavoriteTimelineResult { @@ -47,6 +48,8 @@ export interface OpenTimelineResult { pinnedEventIds?: Readonly> | null; savedObjectId?: string | null; title?: string | null; + templateTimelineId?: string | null; + type?: TimelineType.template | TimelineType.default; updated?: number | null; updatedBy?: string | null; } diff --git a/x-pack/plugins/siem/public/components/recent_timelines/index.tsx b/x-pack/plugins/siem/public/components/recent_timelines/index.tsx index 5b851701b973c4..b641038f35ba6d 100644 --- a/x-pack/plugins/siem/public/components/recent_timelines/index.tsx +++ b/x-pack/plugins/siem/public/components/recent_timelines/index.tsx @@ -6,11 +6,11 @@ import ApolloClient from 'apollo-client'; import { EuiHorizontalRule, EuiLink, EuiText } from '@elastic/eui'; -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, useEffect } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { Dispatch } from 'redux'; -import { AllTimelinesQuery } from '../../containers/timeline/all'; +import { useGetAllTimeline } from '../../containers/timeline/all'; import { SortFieldTimeline, Direction } from '../../graphql/types'; import { queryTimelineById, dispatchUpdateTimeline } from '../open_timeline/helpers'; import { OnOpenTimeline } from '../open_timeline/types'; @@ -62,35 +62,39 @@ const StatefulRecentTimelinesComponent = React.memo( [filterBy] ); - return ( - { + fetchAllTimeline({ + pageInfo: { pageIndex: 1, pageSize: PAGE_SIZE, - }} - search={''} - sort={{ + }, + search: '', + sort: { sortField: SortFieldTimeline.updated, sortOrder: Direction.desc, - }} - onlyUserFavorite={filterBy === 'favorites'} - > - {({ timelines, loading }) => ( - <> - {loading ? ( - loadingPlaceholders - ) : ( - - )} - - {linkAllTimelines} - + }, + onlyUserFavorite: filterBy === 'favorites', + timelines, + totalCount, + }); + }, [filterBy, timelines, totalCount]); + + return ( + <> + {loading ? ( + loadingPlaceholders + ) : ( + )} - + + {linkAllTimelines} + ); } ); diff --git a/x-pack/plugins/siem/public/components/timeline/selectable_timeline/index.tsx b/x-pack/plugins/siem/public/components/timeline/selectable_timeline/index.tsx index 639d30bbe7bb90..4cc89e5bdba73d 100644 --- a/x-pack/plugins/siem/public/components/timeline/selectable_timeline/index.tsx +++ b/x-pack/plugins/siem/public/components/timeline/selectable_timeline/index.tsx @@ -17,11 +17,11 @@ import { EuiFilterButton, } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; -import React, { memo, useCallback, useMemo, useState } from 'react'; +import React, { memo, useCallback, useMemo, useState, useEffect } from 'react'; import { ListProps } from 'react-virtualized'; import styled from 'styled-components'; -import { AllTimelinesQuery } from '../../../containers/timeline/all'; +import { useGetAllTimeline } from '../../../containers/timeline/all'; import { SortFieldTimeline, Direction } from '../../../graphql/types'; import { isUntitled } from '../../open_timeline/helpers'; import * as i18nTimeline from '../../open_timeline/translations'; @@ -96,6 +96,7 @@ const SelectableTimelineComponent: React.FC = ({ const [searchTimelineValue, setSearchTimelineValue] = useState(''); const [onlyFavorites, setOnlyFavorites] = useState(false); const [searchRef, setSearchRef] = useState(null); + const { fetchAllTimeline, timelines, loading, totalCount: timelineCount } = useGetAllTimeline(); const onSearchTimeline = useCallback(val => { setSearchTimelineValue(val); @@ -215,61 +216,64 @@ const SelectableTimelineComponent: React.FC = ({ [searchRef, onlyFavorites, handleOnToggleOnlyFavorites] ); + useEffect(() => { + fetchAllTimeline({ + pageInfo: { + pageIndex: 1, + pageSize, + }, + search: searchTimelineValue, + sort: { + sortField: SortFieldTimeline.updated, + sortOrder: Direction.desc, + }, + onlyUserFavorite: onlyFavorites, + timelines, + totalCount: timelineCount, + }); + }, [onlyFavorites, pageSize, searchTimelineValue, timelines, timelineCount]); + return ( - <> - + !hideUntitled || t.title !== '').length, + timelineCount + ), + } as unknown) as ListProps, + }} + renderOption={renderTimelineOption} + onChange={handleTimelineChange} + searchable + searchProps={{ + 'data-test-subj': 'timeline-super-select-search-box', + isLoading: loading, + placeholder: i18n.SEARCH_BOX_TIMELINE_PLACEHOLDER, + onSearch: onSearchTimeline, + incremental: false, + inputRef: (ref: HTMLElement) => { + setSearchRef(ref); + }, }} - search={searchTimelineValue} - sort={{ sortField: SortFieldTimeline.updated, sortOrder: Direction.desc }} - onlyUserFavorite={onlyFavorites} + singleSelection={true} + options={getSelectableOptions({ timelines, onlyFavorites, searchTimelineValue })} > - {({ timelines, loading, totalCount }) => ( - - !hideUntitled || t.title !== '').length, - totalCount - ), - } as unknown) as ListProps, - }} - renderOption={renderTimelineOption} - onChange={handleTimelineChange} - searchable - searchProps={{ - 'data-test-subj': 'timeline-super-select-search-box', - isLoading: loading, - placeholder: i18n.SEARCH_BOX_TIMELINE_PLACEHOLDER, - onSearch: onSearchTimeline, - incremental: false, - inputRef: (ref: HTMLElement) => { - setSearchRef(ref); - }, - }} - singleSelection={true} - options={getSelectableOptions({ timelines, onlyFavorites, searchTimelineValue })} - > - {(list, search) => ( - <> - {search} - {favoritePortal} - {list} - - )} - - + {(list, search) => ( + <> + {search} + {favoritePortal} + {list} + )} - - + + ); }; diff --git a/x-pack/plugins/siem/public/containers/timeline/all/api.ts b/x-pack/plugins/siem/public/containers/timeline/all/api.ts deleted file mode 100644 index 09c8374bad1138..00000000000000 --- a/x-pack/plugins/siem/public/containers/timeline/all/api.ts +++ /dev/null @@ -1,48 +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 { TIMELINE_IMPORT_URL, TIMELINE_EXPORT_URL } from '../../../../common/constants'; -import { ImportDataProps, ImportDataResponse } from '../../detection_engine/rules'; -import { KibanaServices } from '../../../lib/kibana'; -import { ExportSelectedData } from '../../../components/generic_downloader'; - -export const importTimelines = async ({ - fileToImport, - overwrite = false, - signal, -}: ImportDataProps): Promise => { - const formData = new FormData(); - formData.append('file', fileToImport); - - return KibanaServices.get().http.fetch(`${TIMELINE_IMPORT_URL}`, { - method: 'POST', - headers: { 'Content-Type': undefined }, - query: { overwrite }, - body: formData, - signal, - }); -}; - -export const exportSelectedTimeline: ExportSelectedData = async ({ - excludeExportDetails = false, - filename = `timelines_export.ndjson`, - ids = [], - signal, -}): Promise => { - const body = ids.length > 0 ? JSON.stringify({ ids }) : undefined; - const response = await KibanaServices.get().http.fetch(`${TIMELINE_EXPORT_URL}`, { - method: 'POST', - body, - query: { - exclude_export_details: excludeExportDetails, - file_name: filename, - }, - signal, - asResponse: true, - }); - - return response.body!; -}; diff --git a/x-pack/plugins/siem/public/containers/timeline/all/index.gql_query.ts b/x-pack/plugins/siem/public/containers/timeline/all/index.gql_query.ts index e380e46e77070c..7d30b6c22a1100 100644 --- a/x-pack/plugins/siem/public/containers/timeline/all/index.gql_query.ts +++ b/x-pack/plugins/siem/public/containers/timeline/all/index.gql_query.ts @@ -55,6 +55,9 @@ export const allTimelinesQuery = gql` noteIds pinnedEventIds title + timelineType + templateTimelineId + templateTimelineVersion created createdBy updated diff --git a/x-pack/plugins/siem/public/containers/timeline/all/index.tsx b/x-pack/plugins/siem/public/containers/timeline/all/index.tsx index b5c91ca287f0b8..62c8d21a2e9448 100644 --- a/x-pack/plugins/siem/public/containers/timeline/all/index.tsx +++ b/x-pack/plugins/siem/public/containers/timeline/all/index.tsx @@ -3,23 +3,28 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { useCallback } from 'react'; -import { getOr } from 'lodash/fp'; -import memoizeOne from 'memoize-one'; -import { Query } from 'react-apollo'; +import { getOr, noop } from 'lodash/fp'; +import memoizeOne from 'memoize-one'; +import { useCallback, useState, useRef, useEffect } from 'react'; +import { useDispatch } from 'react-redux'; -import { ApolloQueryResult } from 'apollo-client'; import { OpenTimelineResult } from '../../../components/open_timeline/types'; +import { errorToToaster, useStateToaster } from '../../../components/toasters'; import { GetAllTimeline, PageInfoTimeline, SortTimeline, TimelineResult, } from '../../../graphql/types'; +import { inputsModel, inputsActions } from '../../../store/inputs'; +import { useApolloClient } from '../../../utils/apollo_context'; + import { allTimelinesQuery } from './index.gql_query'; +import * as i18n from '../../../pages/timelines/translations'; export interface AllTimelinesArgs { + fetchAllTimeline: ({ onlyUserFavorite, pageInfo, search, sort }: AllTimelinesVariables) => void; timelines: OpenTimelineResult[]; loading: boolean; totalCount: number; @@ -31,17 +36,13 @@ export interface AllTimelinesVariables { pageInfo: PageInfoTimeline; search: string; sort: SortTimeline; + timelines: OpenTimelineResult[]; + totalCount: number; } -interface OwnProps extends AllTimelinesVariables { - children?: (args: AllTimelinesArgs) => React.ReactNode; -} - -type Refetch = ( - variables: GetAllTimeline.Variables | undefined -) => Promise>; +export const ALL_TIMELINE_QUERY_ID = 'FETCH_ALL_TIMELINES'; -const getAllTimeline = memoizeOne( +export const getAllTimeline = memoizeOne( (variables: string, timelines: TimelineResult[]): OpenTimelineResult[] => timelines.map(timeline => ({ created: timeline.created, @@ -76,41 +77,117 @@ const getAllTimeline = memoizeOne( })) ); -const AllTimelinesQueryComponent: React.FC = ({ - children, - onlyUserFavorite, - pageInfo, - search, - sort, -}) => { - const variables: GetAllTimeline.Variables = { - onlyUserFavorite, - pageInfo, - search, - sort, - }; - const handleRefetch = useCallback((refetch: Refetch) => refetch(variables), [variables]); +export const useGetAllTimeline = (): AllTimelinesArgs => { + const dispatch = useDispatch(); + const apolloClient = useApolloClient(); + const refetch = useRef(); + const [, dispatchToaster] = useStateToaster(); + const [allTimelines, setAllTimelines] = useState({ + fetchAllTimeline: noop, + loading: false, + refetch: refetch.current ?? noop, + totalCount: 0, + timelines: [], + }); + + const fetchAllTimeline = useCallback( + async ({ + onlyUserFavorite, + pageInfo, + search, + sort, + timelines, + totalCount, + }: AllTimelinesVariables) => { + let didCancel = false; + const abortCtrl = new AbortController(); - return ( - - query={allTimelinesQuery} - fetchPolicy="network-only" - notifyOnNetworkStatusChange - variables={variables} - > - {({ data, loading, refetch }) => - children!({ - loading, - refetch: handleRefetch.bind(null, refetch), - totalCount: getOr(0, 'getAllTimeline.totalCount', data), - timelines: getAllTimeline( - JSON.stringify(variables), - getOr([], 'getAllTimeline.timeline', data) - ), - }) - } - + const fetchData = async () => { + try { + if (apolloClient != null) { + setAllTimelines({ + ...allTimelines, + timelines: timelines ?? allTimelines.timelines, + totalCount: totalCount ?? allTimelines.totalCount, + loading: true, + }); + const variables: GetAllTimeline.Variables = { + onlyUserFavorite, + pageInfo, + search, + sort, + }; + const response = await apolloClient.query< + GetAllTimeline.Query, + GetAllTimeline.Variables + >({ + query: allTimelinesQuery, + fetchPolicy: 'network-only', + variables, + context: { + fetchOptions: { + abortSignal: abortCtrl.signal, + }, + }, + }); + if (!didCancel) { + dispatch( + inputsActions.setQuery({ + inputId: 'global', + id: ALL_TIMELINE_QUERY_ID, + loading: false, + refetch: refetch.current ?? noop, + inspect: null, + }) + ); + setAllTimelines({ + fetchAllTimeline, + loading: false, + refetch: refetch.current ?? noop, + totalCount: getOr(0, 'getAllTimeline.totalCount', response.data), + timelines: getAllTimeline( + JSON.stringify(variables), + getOr([], 'getAllTimeline.timeline', response.data) + ), + }); + } + } + } catch (error) { + if (!didCancel) { + errorToToaster({ + title: i18n.ERROR_FETCHING_TIMELINES_TITLE, + error: error.body && error.body.message ? new Error(error.body.message) : error, + dispatchToaster, + }); + setAllTimelines({ + fetchAllTimeline, + loading: false, + refetch: noop, + totalCount: 0, + timelines: [], + }); + } + } + }; + refetch.current = fetchData; + fetchData(); + return () => { + didCancel = true; + abortCtrl.abort(); + }; + }, + [apolloClient, allTimelines] ); -}; -export const AllTimelinesQuery = React.memo(AllTimelinesQueryComponent); + useEffect(() => { + return () => { + dispatch(inputsActions.deleteOneQuery({ inputId: 'global', id: ALL_TIMELINE_QUERY_ID })); + }; + }, [dispatch]); + + return { + ...allTimelines, + fetchAllTimeline, + refetch: refetch.current ?? noop, + }; +}; diff --git a/x-pack/plugins/siem/public/containers/timeline/api.ts b/x-pack/plugins/siem/public/containers/timeline/api.ts new file mode 100644 index 00000000000000..023e2e6af9f88e --- /dev/null +++ b/x-pack/plugins/siem/public/containers/timeline/api.ts @@ -0,0 +1,115 @@ +/* + * 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 { fold } from 'fp-ts/lib/Either'; +import { identity } from 'fp-ts/lib/function'; +import { pipe } from 'fp-ts/lib/pipeable'; + +import { throwErrors } from '../../../../case/common/api'; +import { + SavedTimeline, + TimelineResponse, + TimelineResponseType, +} from '../../../common/types/timeline'; +import { TIMELINE_URL, TIMELINE_IMPORT_URL, TIMELINE_EXPORT_URL } from '../../../common/constants'; + +import { KibanaServices } from '../../lib/kibana'; +import { ExportSelectedData } from '../../components/generic_downloader'; + +import { createToasterPlainError } from '../case/utils'; +import { ImportDataProps, ImportDataResponse } from '../detection_engine/rules'; + +interface RequestPostTimeline { + timeline: SavedTimeline; + signal?: AbortSignal; +} + +interface RequestPatchTimeline extends RequestPostTimeline { + timelineId: T; + version: T; +} + +type RequestPersistTimeline = RequestPostTimeline & Partial>; + +const decodeTimelineResponse = (respTimeline?: TimelineResponse) => + pipe( + TimelineResponseType.decode(respTimeline), + fold(throwErrors(createToasterPlainError), identity) + ); + +const postTimeline = async ({ timeline }: RequestPostTimeline): Promise => { + const response = await KibanaServices.get().http.post(TIMELINE_URL, { + method: 'POST', + body: JSON.stringify({ timeline }), + }); + + return decodeTimelineResponse(response); +}; + +const patchTimeline = async ({ + timelineId, + timeline, + version, +}: RequestPatchTimeline): Promise => { + const response = await KibanaServices.get().http.patch(TIMELINE_URL, { + method: 'PATCH', + body: JSON.stringify({ timeline, timelineId, version }), + }); + + return decodeTimelineResponse(response); +}; + +export const persistTimeline = async ({ + timelineId, + timeline, + version, +}: RequestPersistTimeline): Promise => { + if (timelineId == null) { + return postTimeline({ timeline }); + } + return patchTimeline({ + timelineId, + timeline, + version: version ?? '', + }); +}; + +export const importTimelines = async ({ + fileToImport, + overwrite = false, + signal, +}: ImportDataProps): Promise => { + const formData = new FormData(); + formData.append('file', fileToImport); + + return KibanaServices.get().http.fetch(`${TIMELINE_IMPORT_URL}`, { + method: 'POST', + headers: { 'Content-Type': undefined }, + query: { overwrite }, + body: formData, + signal, + }); +}; + +export const exportSelectedTimeline: ExportSelectedData = async ({ + excludeExportDetails = false, + filename = `timelines_export.ndjson`, + ids = [], + signal, +}): Promise => { + const body = ids.length > 0 ? JSON.stringify({ ids }) : undefined; + const response = await KibanaServices.get().http.fetch(`${TIMELINE_EXPORT_URL}`, { + method: 'POST', + body, + query: { + exclude_export_details: excludeExportDetails, + file_name: filename, + }, + signal, + asResponse: true, + }); + + return response.body!; +}; diff --git a/x-pack/plugins/siem/public/graphql/introspection.json b/x-pack/plugins/siem/public/graphql/introspection.json index 2a9dd8f2aacfe8..4026a043c7778c 100644 --- a/x-pack/plugins/siem/public/graphql/introspection.json +++ b/x-pack/plugins/siem/public/graphql/introspection.json @@ -9728,6 +9728,30 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "templateTimelineId", + "description": "", + "args": [], + "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "templateTimelineVersion", + "description": "", + "args": [], + "type": { "kind": "SCALAR", "name": "Int", "ofType": null }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "timelineType", + "description": "", + "args": [], + "type": { "kind": "ENUM", "name": "TimelineType", "ofType": null }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "updated", "description": "", @@ -10323,6 +10347,39 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "SCALAR", + "name": "Int", + "description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "TimelineType", + "description": "", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "default", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "template", + "description": "", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "PageInfoTimeline", @@ -10863,6 +10920,24 @@ "type": { "kind": "SCALAR", "name": "String", "ofType": null }, "defaultValue": null }, + { + "name": "templateTimelineId", + "description": "", + "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "defaultValue": null + }, + { + "name": "templateTimelineVersion", + "description": "", + "type": { "kind": "SCALAR", "name": "Int", "ofType": null }, + "defaultValue": null + }, + { + "name": "timelineType", + "description": "", + "type": { "kind": "ENUM", "name": "TimelineType", "ofType": null }, + "defaultValue": null + }, { "name": "dateRange", "description": "", diff --git a/x-pack/plugins/siem/public/graphql/types.ts b/x-pack/plugins/siem/public/graphql/types.ts index e15c099a007ad3..8c39d5e58b99e1 100644 --- a/x-pack/plugins/siem/public/graphql/types.ts +++ b/x-pack/plugins/siem/public/graphql/types.ts @@ -132,6 +132,12 @@ export interface TimelineInput { title?: Maybe; + templateTimelineId?: Maybe; + + templateTimelineVersion?: Maybe; + + timelineType?: Maybe; + dateRange?: Maybe; savedQueryId?: Maybe; @@ -334,6 +340,11 @@ export enum TlsFields { _id = '_id', } +export enum TimelineType { + default = 'default', + template = 'template', +} + export enum SortFieldTimeline { title = 'title', description = 'description', @@ -1944,6 +1955,12 @@ export interface TimelineResult { title?: Maybe; + templateTimelineId?: Maybe; + + templateTimelineVersion?: Maybe; + + timelineType?: Maybe; + updated?: Maybe; updatedBy?: Maybe; @@ -4030,6 +4047,12 @@ export namespace GetAllTimeline { title: Maybe; + timelineType: Maybe; + + templateTimelineId: Maybe; + + templateTimelineVersion: Maybe; + created: Maybe; createdBy: Maybe; diff --git a/x-pack/plugins/siem/public/mock/timeline_results.ts b/x-pack/plugins/siem/public/mock/timeline_results.ts index 0e61457873bfde..edd1c737718296 100644 --- a/x-pack/plugins/siem/public/mock/timeline_results.ts +++ b/x-pack/plugins/siem/public/mock/timeline_results.ts @@ -168,6 +168,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 1', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -294,6 +297,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 2', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -420,6 +426,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 2', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -546,6 +555,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 3', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -672,6 +684,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 4', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -798,6 +813,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 5', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -924,6 +942,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 6', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -1050,6 +1071,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 7', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -1176,6 +1200,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 7', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -1302,6 +1329,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 7', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -1428,6 +1458,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 7', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -1554,6 +1587,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 7', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, @@ -1680,6 +1716,9 @@ export const mockOpenTimelineQueryResults: MockedProvidedQuery[] = [ 'ZF0W12oB9v5HJNSHwY6L', ], title: 'test 7', + timelineType: null, + templateTimelineId: null, + templateTimelineVersion: null, created: 1558386787614, createdBy: 'elastic', updated: 1558390951234, diff --git a/x-pack/plugins/siem/public/pages/timelines/translations.ts b/x-pack/plugins/siem/public/pages/timelines/translations.ts index 723d164ad2cdd5..304474bbff2c54 100644 --- a/x-pack/plugins/siem/public/pages/timelines/translations.ts +++ b/x-pack/plugins/siem/public/pages/timelines/translations.ts @@ -23,3 +23,10 @@ export const ALL_TIMELINES_IMPORT_TIMELINE_TITLE = i18n.translate( defaultMessage: 'Import Timeline', } ); + +export const ERROR_FETCHING_TIMELINES_TITLE = i18n.translate( + 'xpack.siem.timelines.allTimelines.errorFetchingTimelinesTitle', + { + defaultMessage: 'Failed to query all timelines data', + } +); diff --git a/x-pack/plugins/siem/public/store/store.ts b/x-pack/plugins/siem/public/store/store.ts index d3559e7a7adde9..2af0f87b4494d9 100644 --- a/x-pack/plugins/siem/public/store/store.ts +++ b/x-pack/plugins/siem/public/store/store.ts @@ -32,6 +32,7 @@ export const createStore = ( const middlewareDependencies = { apolloClient$: apolloClient, + selectAllTimelineQuery: inputsSelectors.globalQueryByIdSelector, selectNotesByIdSelector: appSelectors.selectNotesByIdSelector, timelineByIdSelector: timelineSelectors.timelineByIdSelector, timelineTimeRangeSelector: inputsSelectors.timelineTimeRangeSelector, diff --git a/x-pack/plugins/siem/public/store/timeline/epic.ts b/x-pack/plugins/siem/public/store/timeline/epic.ts index 4fece0572274f3..6812d8d8aa672b 100644 --- a/x-pack/plugins/siem/public/store/timeline/epic.ts +++ b/x-pack/plugins/siem/public/store/timeline/epic.ts @@ -29,17 +29,11 @@ import { } from 'rxjs/operators'; import { esFilters, Filter, MatchAllFilter } from '../../../../../../src/plugins/data/public'; -import { persistTimelineMutation } from '../../containers/timeline/persist.gql_query'; -import { - PersistTimelineMutation, - TimelineInput, - ResponseTimeline, - TimelineResult, -} from '../../graphql/types'; +import { TimelineInput, ResponseTimeline, TimelineResult } from '../../graphql/types'; import { AppApolloClient } from '../../lib/lib'; import { addError } from '../app/actions'; import { NotesById } from '../app/model'; -import { TimeRange } from '../inputs/model'; +import { inputsModel } from '../inputs'; import { applyKqlFilterQuery, @@ -75,13 +69,15 @@ import { epicPersistPinnedEvent, timelinePinnedEventActionsType } from './epic_p import { epicPersistTimelineFavorite, timelineFavoriteActionsType } from './epic_favorite'; import { isNotNull } from './helpers'; import { dispatcherTimelinePersistQueue } from './epic_dispatcher_timeline_persistence_queue'; -import { refetchQueries } from './refetch_queries'; import { myEpicTimelineId } from './my_epic_timeline_id'; import { ActionTimeline, TimelineById } from './types'; +import { persistTimeline } from '../../containers/timeline/api'; +import { ALL_TIMELINE_QUERY_ID } from '../../containers/timeline/all'; interface TimelineEpicDependencies { timelineByIdSelector: (state: State) => TimelineById; - timelineTimeRangeSelector: (state: State) => TimeRange; + timelineTimeRangeSelector: (state: State) => inputsModel.TimeRange; + selectAllTimelineQuery: () => (state: State, id: string) => inputsModel.GlobalQuery; selectNotesByIdSelector: (state: State) => NotesById; apolloClient$: Observable; } @@ -119,10 +115,24 @@ export const createTimelineEpic = (): Epic< > => ( action$, state$, - { selectNotesByIdSelector, timelineByIdSelector, timelineTimeRangeSelector, apolloClient$ } + { + selectAllTimelineQuery, + selectNotesByIdSelector, + timelineByIdSelector, + timelineTimeRangeSelector, + apolloClient$, + } ) => { const timeline$ = state$.pipe(map(timelineByIdSelector), filter(isNotNull)); + const allTimelineQuery$ = state$.pipe( + map(state => { + const getQuery = selectAllTimelineQuery(); + return getQuery(state, ALL_TIMELINE_QUERY_ID); + }), + filter(isNotNull) + ); + const notes$ = state$.pipe(map(selectNotesByIdSelector), filter(isNotNull)); const timelineTimeRange$ = state$.pipe(map(timelineTimeRangeSelector), filter(isNotNull)); @@ -168,33 +178,52 @@ export const createTimelineEpic = (): Epic< const version = myEpicTimelineId.getTimelineVersion(); if (timelineNoteActionsType.includes(action.type)) { - return epicPersistNote(apolloClient, action, timeline, notes, action$, timeline$, notes$); + return epicPersistNote( + apolloClient, + action, + timeline, + notes, + action$, + timeline$, + notes$, + allTimelineQuery$ + ); } else if (timelinePinnedEventActionsType.includes(action.type)) { - return epicPersistPinnedEvent(apolloClient, action, timeline, action$, timeline$); + return epicPersistPinnedEvent( + apolloClient, + action, + timeline, + action$, + timeline$, + allTimelineQuery$ + ); } else if (timelineFavoriteActionsType.includes(action.type)) { - return epicPersistTimelineFavorite(apolloClient, action, timeline, action$, timeline$); + return epicPersistTimelineFavorite( + apolloClient, + action, + timeline, + action$, + timeline$, + allTimelineQuery$ + ); } else if (timelineActionsType.includes(action.type)) { return from( - apolloClient.mutate< - PersistTimelineMutation.Mutation, - PersistTimelineMutation.Variables - >({ - mutation: persistTimelineMutation, - fetchPolicy: 'no-cache', - variables: { - timelineId, - version, - timeline: convertTimelineAsInput(timeline[action.payload.id], timelineTimeRange), - }, - refetchQueries, + persistTimeline({ + timelineId, + version, + timeline: convertTimelineAsInput(timeline[action.payload.id], timelineTimeRange), }) ).pipe( - withLatestFrom(timeline$), - mergeMap(([result, recentTimeline]) => { + withLatestFrom(timeline$, allTimelineQuery$), + mergeMap(([result, recentTimeline, allTimelineQuery]) => { const savedTimeline = recentTimeline[action.payload.id]; const response: ResponseTimeline = get('data.persistTimeline', result); const callOutMsg = response.code === 403 ? [showCallOutUnauthorizedMsg()] : []; + if (allTimelineQuery.refetch != null) { + (allTimelineQuery.refetch as inputsModel.Refetch)(); + } + return [ response.code === 409 ? updateAutoSaveMsg({ @@ -261,7 +290,7 @@ const timelineInput: TimelineInput = { export const convertTimelineAsInput = ( timeline: TimelineModel, - timelineTimeRange: TimeRange + timelineTimeRange: inputsModel.TimeRange ): TimelineInput => Object.keys(timelineInput).reduce((acc, key) => { if (has(key, timeline)) { diff --git a/x-pack/plugins/siem/public/store/timeline/epic_favorite.ts b/x-pack/plugins/siem/public/store/timeline/epic_favorite.ts index 4d1b73aa70a6ee..6a1dadb8a59f59 100644 --- a/x-pack/plugins/siem/public/store/timeline/epic_favorite.ts +++ b/x-pack/plugins/siem/public/store/timeline/epic_favorite.ts @@ -26,6 +26,7 @@ import { dispatcherTimelinePersistQueue } from './epic_dispatcher_timeline_persi import { refetchQueries } from './refetch_queries'; import { myEpicTimelineId } from './my_epic_timeline_id'; import { ActionTimeline, TimelineById } from './types'; +import { inputsModel } from '../inputs'; export const timelineFavoriteActionsType = [updateIsFavorite.type]; @@ -34,7 +35,8 @@ export const epicPersistTimelineFavorite = ( action: ActionTimeline, timeline: TimelineById, action$: Observable, - timeline$: Observable + timeline$: Observable, + allTimelineQuery$: Observable // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Observable => from( @@ -50,12 +52,16 @@ export const epicPersistTimelineFavorite = ( refetchQueries, }) ).pipe( - withLatestFrom(timeline$), - mergeMap(([result, recentTimelines]) => { + withLatestFrom(timeline$, allTimelineQuery$), + mergeMap(([result, recentTimelines, allTimelineQuery]) => { const savedTimeline = recentTimelines[action.payload.id]; const response: ResponseFavoriteTimeline = get('data.persistFavorite', result); const callOutMsg = response.code === 403 ? [showCallOutUnauthorizedMsg()] : []; + if (allTimelineQuery.refetch != null) { + (allTimelineQuery.refetch as inputsModel.Refetch)(); + } + return [ ...callOutMsg, updateTimeline({ diff --git a/x-pack/plugins/siem/public/store/timeline/epic_note.ts b/x-pack/plugins/siem/public/store/timeline/epic_note.ts index e5a712fe2c666f..3722a6ad8036ca 100644 --- a/x-pack/plugins/siem/public/store/timeline/epic_note.ts +++ b/x-pack/plugins/siem/public/store/timeline/epic_note.ts @@ -16,6 +16,7 @@ import { persistTimelineNoteMutation } from '../../containers/timeline/notes/per import { PersistTimelineNoteMutation, ResponseNote } from '../../graphql/types'; import { updateNote, addError } from '../app/actions'; import { NotesById } from '../app/model'; +import { inputsModel } from '../inputs'; import { addNote, @@ -39,7 +40,8 @@ export const epicPersistNote = ( notes: NotesById, action$: Observable, timeline$: Observable, - notes$: Observable + notes$: Observable, + allTimelineQuery$: Observable // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Observable => from( @@ -61,12 +63,16 @@ export const epicPersistNote = ( refetchQueries, }) ).pipe( - withLatestFrom(timeline$, notes$), - mergeMap(([result, recentTimeline, recentNotes]) => { + withLatestFrom(timeline$, notes$, allTimelineQuery$), + mergeMap(([result, recentTimeline, recentNotes, allTimelineQuery]) => { const noteIdRedux = action.payload.noteId; const response: ResponseNote = get('data.persistNote', result); const callOutMsg = response.code === 403 ? [showCallOutUnauthorizedMsg()] : []; + if (allTimelineQuery.refetch != null) { + (allTimelineQuery.refetch as inputsModel.Refetch)(); + } + return [ ...callOutMsg, recentTimeline[action.payload.id].savedObjectId == null diff --git a/x-pack/plugins/siem/public/store/timeline/epic_pinned_event.ts b/x-pack/plugins/siem/public/store/timeline/epic_pinned_event.ts index 2260999a91e7bc..a1281250ba72af 100644 --- a/x-pack/plugins/siem/public/store/timeline/epic_pinned_event.ts +++ b/x-pack/plugins/siem/public/store/timeline/epic_pinned_event.ts @@ -15,6 +15,8 @@ import { filter, mergeMap, startWith, withLatestFrom, takeUntil } from 'rxjs/ope import { persistTimelinePinnedEventMutation } from '../../containers/timeline/pinned_event/persist.gql_query'; import { PersistTimelinePinnedEventMutation, PinnedEvent } from '../../graphql/types'; import { addError } from '../app/actions'; +import { inputsModel } from '../inputs'; + import { pinEvent, endTimelineSaving, @@ -35,7 +37,8 @@ export const epicPersistPinnedEvent = ( action: ActionTimeline, timeline: TimelineById, action$: Observable, - timeline$: Observable + timeline$: Observable, + allTimelineQuery$: Observable // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Observable => from( @@ -57,12 +60,16 @@ export const epicPersistPinnedEvent = ( refetchQueries, }) ).pipe( - withLatestFrom(timeline$), - mergeMap(([result, recentTimeline]) => { + withLatestFrom(timeline$, allTimelineQuery$), + mergeMap(([result, recentTimeline, allTimelineQuery]) => { const savedTimeline = recentTimeline[action.payload.id]; const response: PinnedEvent = get('data.persistPinnedEventOnTimeline', result); const callOutMsg = response && response.code === 403 ? [showCallOutUnauthorizedMsg()] : []; + if (allTimelineQuery.refetch != null) { + (allTimelineQuery.refetch as inputsModel.Refetch)(); + } + return [ response != null ? updateTimeline({ diff --git a/x-pack/plugins/siem/server/graphql/timeline/schema.gql.ts b/x-pack/plugins/siem/server/graphql/timeline/schema.gql.ts index 9dd04247b7f47c..bc2b3a53d85f3e 100644 --- a/x-pack/plugins/siem/server/graphql/timeline/schema.gql.ts +++ b/x-pack/plugins/siem/server/graphql/timeline/schema.gql.ts @@ -125,6 +125,11 @@ export const timelineSchema = gql` script: String } + enum TimelineType { + default + template + } + input TimelineInput { columns: [ColumnHeaderInput!] dataProviders: [DataProviderInput!] @@ -134,6 +139,9 @@ export const timelineSchema = gql` kqlMode: String kqlQuery: SerializedFilterQueryInput title: String + templateTimelineId: String + templateTimelineVersion: Int + timelineType: TimelineType dateRange: DateRangePickerInput savedQueryId: String sort: SortTimelineInput @@ -237,6 +245,9 @@ export const timelineSchema = gql` savedObjectId: String! sort: SortTimelineResult title: String + templateTimelineId: String + templateTimelineVersion: Int + timelineType: TimelineType updated: Float updatedBy: String version: String! diff --git a/x-pack/plugins/siem/server/graphql/types.ts b/x-pack/plugins/siem/server/graphql/types.ts index d272b7ff59b79a..6a35ba08f8e43f 100644 --- a/x-pack/plugins/siem/server/graphql/types.ts +++ b/x-pack/plugins/siem/server/graphql/types.ts @@ -134,6 +134,12 @@ export interface TimelineInput { title?: Maybe; + templateTimelineId?: Maybe; + + templateTimelineVersion?: Maybe; + + timelineType?: Maybe; + dateRange?: Maybe; savedQueryId?: Maybe; @@ -336,6 +342,11 @@ export enum TlsFields { _id = '_id', } +export enum TimelineType { + default = 'default', + template = 'template', +} + export enum SortFieldTimeline { title = 'title', description = 'description', @@ -1946,6 +1957,12 @@ export interface TimelineResult { title?: Maybe; + templateTimelineId?: Maybe; + + templateTimelineVersion?: Maybe; + + timelineType?: Maybe; + updated?: Maybe; updatedBy?: Maybe; @@ -8023,6 +8040,12 @@ export namespace TimelineResultResolvers { title?: TitleResolver, TypeParent, TContext>; + templateTimelineId?: TemplateTimelineIdResolver, TypeParent, TContext>; + + templateTimelineVersion?: TemplateTimelineVersionResolver, TypeParent, TContext>; + + timelineType?: TimelineTypeResolver, TypeParent, TContext>; + updated?: UpdatedResolver, TypeParent, TContext>; updatedBy?: UpdatedByResolver, TypeParent, TContext>; @@ -8130,6 +8153,21 @@ export namespace TimelineResultResolvers { Parent = TimelineResult, TContext = SiemContext > = Resolver; + export type TemplateTimelineIdResolver< + R = Maybe, + Parent = TimelineResult, + TContext = SiemContext + > = Resolver; + export type TemplateTimelineVersionResolver< + R = Maybe, + Parent = TimelineResult, + TContext = SiemContext + > = Resolver; + export type TimelineTypeResolver< + R = Maybe, + Parent = TimelineResult, + TContext = SiemContext + > = Resolver; export type UpdatedResolver< R = Maybe, Parent = TimelineResult, diff --git a/x-pack/plugins/siem/server/lib/compose/kibana.ts b/x-pack/plugins/siem/server/lib/compose/kibana.ts index 9c46f3320e37ec..4a595032e43eb2 100644 --- a/x-pack/plugins/siem/server/lib/compose/kibana.ts +++ b/x-pack/plugins/siem/server/lib/compose/kibana.ts @@ -27,9 +27,9 @@ import { ElasticsearchSourceStatusAdapter, SourceStatus } from '../source_status import { ConfigurationSourcesAdapter, Sources } from '../sources'; import { AppBackendLibs, AppDomainLibs } from '../types'; import { ElasticsearchUncommonProcessesAdapter, UncommonProcesses } from '../uncommon_processes'; -import { Note } from '../note/saved_object'; -import { PinnedEvent } from '../pinned_event/saved_object'; -import { Timeline } from '../timeline/saved_object'; +import * as note from '../note/saved_object'; +import * as pinnedEvent from '../pinned_event/saved_object'; +import * as timeline from '../timeline/saved_object'; import { ElasticsearchMatrixHistogramAdapter, MatrixHistogram } from '../matrix_histogram'; export function compose( @@ -41,10 +41,6 @@ export function compose( const sources = new Sources(new ConfigurationSourcesAdapter()); const sourceStatus = new SourceStatus(new ElasticsearchSourceStatusAdapter(framework)); - const timeline = new Timeline(); - const note = new Note(); - const pinnedEvent = new PinnedEvent(); - const domainLibs: AppDomainLibs = { authentications: new Authentications(new ElasticsearchAuthenticationAdapter(framework)), events: new Events(new ElasticsearchEventsAdapter(framework)), diff --git a/x-pack/plugins/siem/server/lib/note/saved_object.ts b/x-pack/plugins/siem/server/lib/note/saved_object.ts index 3eae30625e4223..219465f5514574 100644 --- a/x-pack/plugins/siem/server/lib/note/saved_object.ts +++ b/x-pack/plugins/siem/server/lib/note/saved_object.ts @@ -15,6 +15,11 @@ import { identity } from 'fp-ts/lib/function'; import { SavedObjectsFindOptions } from '../../../../../../src/core/server'; import { AuthenticatedUser } from '../../../../security/common/model'; import { UNAUTHENTICATED_USER } from '../../../common/constants'; +import { + SavedNote, + NoteSavedObjectRuntimeType, + NoteSavedObject, +} from '../../../common/types/timeline/note'; import { PageInfoNote, ResponseNote, @@ -23,178 +28,198 @@ import { NoteResult, } from '../../graphql/types'; import { FrameworkRequest } from '../framework'; -import { SavedNote, NoteSavedObjectRuntimeType, NoteSavedObject } from './types'; import { noteSavedObjectType } from './saved_object_mappings'; import { pickSavedTimeline } from '../timeline/pick_saved_timeline'; import { convertSavedObjectToSavedTimeline } from '../timeline/convert_saved_object_to_savedtimeline'; import { timelineSavedObjectType } from '../timeline/saved_object_mappings'; -export class Note { - public async deleteNote(request: FrameworkRequest, noteIds: string[]) { - const savedObjectsClient = request.context.core.savedObjects.client; - - await Promise.all( - noteIds.map(noteId => savedObjectsClient.delete(noteSavedObjectType, noteId)) - ); - } - - public async deleteNoteByTimelineId(request: FrameworkRequest, timelineId: string) { - const options: SavedObjectsFindOptions = { - type: noteSavedObjectType, - search: timelineId, - searchFields: ['timelineId'], - }; - const notesToBeDeleted = await this.getAllSavedNote(request, options); - const savedObjectsClient = request.context.core.savedObjects.client; - - await Promise.all( - notesToBeDeleted.notes.map(note => - savedObjectsClient.delete(noteSavedObjectType, note.noteId) - ) - ); - } - - public async getNote(request: FrameworkRequest, noteId: string): Promise { - return this.getSavedNote(request, noteId); - } - - public async getNotesByEventId( - request: FrameworkRequest, - eventId: string - ): Promise { - const options: SavedObjectsFindOptions = { - type: noteSavedObjectType, - search: eventId, - searchFields: ['eventId'], - }; - const notesByEventId = await this.getAllSavedNote(request, options); - return notesByEventId.notes; - } - - public async getNotesByTimelineId( - request: FrameworkRequest, - timelineId: string - ): Promise { - const options: SavedObjectsFindOptions = { - type: noteSavedObjectType, - search: timelineId, - searchFields: ['timelineId'], - }; - const notesByTimelineId = await this.getAllSavedNote(request, options); - return notesByTimelineId.notes; - } - - public async getAllNotes( +export interface Note { + deleteNote: (request: FrameworkRequest, noteIds: string[]) => Promise; + deleteNoteByTimelineId: (request: FrameworkRequest, noteIds: string) => Promise; + getNote: (request: FrameworkRequest, noteId: string) => Promise; + getNotesByEventId: (request: FrameworkRequest, noteId: string) => Promise; + getNotesByTimelineId: (request: FrameworkRequest, noteId: string) => Promise; + getAllNotes: ( request: FrameworkRequest, pageInfo: PageInfoNote | null, search: string | null, sort: SortNote | null - ): Promise { - const options: SavedObjectsFindOptions = { - type: noteSavedObjectType, - perPage: pageInfo != null ? pageInfo.pageSize : undefined, - page: pageInfo != null ? pageInfo.pageIndex : undefined, - search: search != null ? search : undefined, - searchFields: ['note'], - sortField: sort != null ? sort.sortField : undefined, - sortOrder: sort != null ? sort.sortOrder : undefined, - }; - return this.getAllSavedNote(request, options); - } - - public async persistNote( + ) => Promise; + persistNote: ( request: FrameworkRequest, noteId: string | null, version: string | null, note: SavedNote - ): Promise { - try { - const savedObjectsClient = request.context.core.savedObjects.client; - - if (noteId == null) { - const timelineVersionSavedObject = - note.timelineId == null - ? await (async () => { - const timelineResult = convertSavedObjectToSavedTimeline( - await savedObjectsClient.create( - timelineSavedObjectType, - pickSavedTimeline(null, {}, request.user) - ) - ); - note.timelineId = timelineResult.savedObjectId; - return timelineResult.version; - })() - : null; - - // Create new note - return { - code: 200, - message: 'success', - note: convertSavedObjectToSavedNote( - await savedObjectsClient.create( - noteSavedObjectType, - pickSavedNote(noteId, note, request.user) - ), - timelineVersionSavedObject != null ? timelineVersionSavedObject : undefined - ), - }; - } + ) => Promise; + convertSavedObjectToSavedNote: ( + savedObject: unknown, + timelineVersion?: string | undefined | null + ) => NoteSavedObject; +} + +export const deleteNote = async (request: FrameworkRequest, noteIds: string[]) => { + const savedObjectsClient = request.context.core.savedObjects.client; + + await Promise.all(noteIds.map(noteId => savedObjectsClient.delete(noteSavedObjectType, noteId))); +}; + +export const deleteNoteByTimelineId = async (request: FrameworkRequest, timelineId: string) => { + const options: SavedObjectsFindOptions = { + type: noteSavedObjectType, + search: timelineId, + searchFields: ['timelineId'], + }; + const notesToBeDeleted = await getAllSavedNote(request, options); + const savedObjectsClient = request.context.core.savedObjects.client; + + await Promise.all( + notesToBeDeleted.notes.map(note => savedObjectsClient.delete(noteSavedObjectType, note.noteId)) + ); +}; + +export const getNote = async ( + request: FrameworkRequest, + noteId: string +): Promise => { + return getSavedNote(request, noteId); +}; + +export const getNotesByEventId = async ( + request: FrameworkRequest, + eventId: string +): Promise => { + const options: SavedObjectsFindOptions = { + type: noteSavedObjectType, + search: eventId, + searchFields: ['eventId'], + }; + const notesByEventId = await getAllSavedNote(request, options); + return notesByEventId.notes; +}; + +export const getNotesByTimelineId = async ( + request: FrameworkRequest, + timelineId: string +): Promise => { + const options: SavedObjectsFindOptions = { + type: noteSavedObjectType, + search: timelineId, + searchFields: ['timelineId'], + }; + const notesByTimelineId = await getAllSavedNote(request, options); + return notesByTimelineId.notes; +}; + +export const getAllNotes = async ( + request: FrameworkRequest, + pageInfo: PageInfoNote | null, + search: string | null, + sort: SortNote | null +): Promise => { + const options: SavedObjectsFindOptions = { + type: noteSavedObjectType, + perPage: pageInfo != null ? pageInfo.pageSize : undefined, + page: pageInfo != null ? pageInfo.pageIndex : undefined, + search: search != null ? search : undefined, + searchFields: ['note'], + sortField: sort != null ? sort.sortField : undefined, + sortOrder: sort != null ? sort.sortOrder : undefined, + }; + return getAllSavedNote(request, options); +}; + +export const persistNote = async ( + request: FrameworkRequest, + noteId: string | null, + version: string | null, + note: SavedNote +): Promise => { + try { + const savedObjectsClient = request.context.core.savedObjects.client; - // Update new note + if (noteId == null) { + const timelineVersionSavedObject = + note.timelineId == null + ? await (async () => { + const timelineResult = convertSavedObjectToSavedTimeline( + await savedObjectsClient.create( + timelineSavedObjectType, + pickSavedTimeline(null, {}, request.user) + ) + ); + note.timelineId = timelineResult.savedObjectId; + return timelineResult.version; + })() + : null; - const existingNote = await this.getSavedNote(request, noteId); + // Create new note return { code: 200, message: 'success', note: convertSavedObjectToSavedNote( - await savedObjectsClient.update( + await savedObjectsClient.create( noteSavedObjectType, - noteId, - pickSavedNote(noteId, note, request.user), - { - version: existingNote.version || undefined, - } - ) + pickSavedNote(noteId, note, request.user) + ), + timelineVersionSavedObject != null ? timelineVersionSavedObject : undefined ), }; - } catch (err) { - if (getOr(null, 'output.statusCode', err) === 403) { - const noteToReturn: NoteResult = { - ...note, - noteId: uuid.v1(), - version: '', - timelineId: '', - timelineVersion: '', - }; - return { - code: 403, - message: err.message, - note: noteToReturn, - }; - } - throw err; } - } - private async getSavedNote(request: FrameworkRequest, NoteId: string) { - const savedObjectsClient = request.context.core.savedObjects.client; - const savedObject = await savedObjectsClient.get(noteSavedObjectType, NoteId); - - return convertSavedObjectToSavedNote(savedObject); - } - - private async getAllSavedNote(request: FrameworkRequest, options: SavedObjectsFindOptions) { - const savedObjectsClient = request.context.core.savedObjects.client; - const savedObjects = await savedObjectsClient.find(options); + // Update new note + const existingNote = await getSavedNote(request, noteId); return { - totalCount: savedObjects.total, - notes: savedObjects.saved_objects.map(savedObject => - convertSavedObjectToSavedNote(savedObject) + code: 200, + message: 'success', + note: convertSavedObjectToSavedNote( + await savedObjectsClient.update( + noteSavedObjectType, + noteId, + pickSavedNote(noteId, note, request.user), + { + version: existingNote.version || undefined, + } + ) ), }; + } catch (err) { + if (getOr(null, 'output.statusCode', err) === 403) { + const noteToReturn: NoteResult = { + ...note, + noteId: uuid.v1(), + version: '', + timelineId: '', + timelineVersion: '', + }; + return { + code: 403, + message: err.message, + note: noteToReturn, + }; + } + throw err; } -} +}; + +const getSavedNote = async (request: FrameworkRequest, NoteId: string) => { + const savedObjectsClient = request.context.core.savedObjects.client; + const savedObject = await savedObjectsClient.get(noteSavedObjectType, NoteId); + + return convertSavedObjectToSavedNote(savedObject); +}; + +const getAllSavedNote = async (request: FrameworkRequest, options: SavedObjectsFindOptions) => { + const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjects = await savedObjectsClient.find(options); + + return { + totalCount: savedObjects.total, + notes: savedObjects.saved_objects.map(savedObject => + convertSavedObjectToSavedNote(savedObject) + ), + }; +}; export const convertSavedObjectToSavedNote = ( savedObject: unknown, diff --git a/x-pack/plugins/siem/server/lib/pinned_event/saved_object.ts b/x-pack/plugins/siem/server/lib/pinned_event/saved_object.ts index 1e3a481e17106f..c653f23d5c1499 100644 --- a/x-pack/plugins/siem/server/lib/pinned_event/saved_object.ts +++ b/x-pack/plugins/siem/server/lib/pinned_event/saved_object.ts @@ -13,174 +13,224 @@ import { identity } from 'fp-ts/lib/function'; import { SavedObjectsFindOptions } from '../../../../../../src/core/server'; import { AuthenticatedUser } from '../../../../security/common/model'; import { UNAUTHENTICATED_USER } from '../../../common/constants'; -import { FrameworkRequest } from '../framework'; import { PinnedEventSavedObject, PinnedEventSavedObjectRuntimeType, SavedPinnedEvent, -} from './types'; +} from '../../../common/types/timeline/pinned_event'; +import { FrameworkRequest } from '../framework'; + import { PageInfoNote, SortNote, PinnedEvent as PinnedEventResponse } from '../../graphql/types'; import { pickSavedTimeline } from '../timeline/pick_saved_timeline'; import { convertSavedObjectToSavedTimeline } from '../timeline/convert_saved_object_to_savedtimeline'; import { pinnedEventSavedObjectType } from './saved_object_mappings'; import { timelineSavedObjectType } from '../timeline/saved_object_mappings'; -export class PinnedEvent { - public async deletePinnedEventOnTimeline(request: FrameworkRequest, pinnedEventIds: string[]) { - const savedObjectsClient = request.context.core.savedObjects.client; - - await Promise.all( - pinnedEventIds.map(pinnedEventId => - savedObjectsClient.delete(pinnedEventSavedObjectType, pinnedEventId) - ) - ); - } +export interface PinnedEvent { + deletePinnedEventOnTimeline: ( + request: FrameworkRequest, + pinnedEventIds: string[] + ) => Promise; - public async deleteAllPinnedEventsOnTimeline(request: FrameworkRequest, timelineId: string) { - const savedObjectsClient = request.context.core.savedObjects.client; - const options: SavedObjectsFindOptions = { - type: pinnedEventSavedObjectType, - search: timelineId, - searchFields: ['timelineId'], - }; - const pinnedEventToBeDeleted = await this.getAllSavedPinnedEvents(request, options); - await Promise.all( - pinnedEventToBeDeleted.map(pinnedEvent => - savedObjectsClient.delete(pinnedEventSavedObjectType, pinnedEvent.pinnedEventId) - ) - ); - } + deleteAllPinnedEventsOnTimeline: (request: FrameworkRequest, timelineId: string) => Promise; - public async getPinnedEvent( + getPinnedEvent: ( request: FrameworkRequest, pinnedEventId: string - ): Promise { - return this.getSavedPinnedEvent(request, pinnedEventId); - } + ) => Promise; - public async getAllPinnedEventsByTimelineId( + getAllPinnedEventsByTimelineId: ( request: FrameworkRequest, timelineId: string - ): Promise { - const options: SavedObjectsFindOptions = { - type: pinnedEventSavedObjectType, - search: timelineId, - searchFields: ['timelineId'], - }; - return this.getAllSavedPinnedEvents(request, options); - } + ) => Promise; - public async getAllPinnedEvents( + getAllPinnedEvents: ( request: FrameworkRequest, pageInfo: PageInfoNote | null, search: string | null, sort: SortNote | null - ): Promise { - const options: SavedObjectsFindOptions = { - type: pinnedEventSavedObjectType, - perPage: pageInfo != null ? pageInfo.pageSize : undefined, - page: pageInfo != null ? pageInfo.pageIndex : undefined, - search: search != null ? search : undefined, - searchFields: ['timelineId', 'eventId'], - sortField: sort != null ? sort.sortField : undefined, - sortOrder: sort != null ? sort.sortOrder : undefined, - }; - return this.getAllSavedPinnedEvents(request, options); - } + ) => Promise; - public async persistPinnedEventOnTimeline( + persistPinnedEventOnTimeline: ( request: FrameworkRequest, pinnedEventId: string | null, // pinned event saved object id eventId: string, timelineId: string | null - ): Promise { - const savedObjectsClient = request.context.core.savedObjects.client; - - try { - if (pinnedEventId == null) { - const timelineVersionSavedObject = - timelineId == null - ? await (async () => { - const timelineResult = convertSavedObjectToSavedTimeline( - await savedObjectsClient.create( - timelineSavedObjectType, - pickSavedTimeline(null, {}, request.user || null) - ) - ); - timelineId = timelineResult.savedObjectId; // eslint-disable-line no-param-reassign - return timelineResult.version; - })() - : null; - - if (timelineId != null) { - const allPinnedEventId = await this.getAllPinnedEventsByTimelineId(request, timelineId); - const isPinnedAlreadyExisting = allPinnedEventId.filter( - pinnedEvent => pinnedEvent.eventId === eventId - ); + ) => Promise; - if (isPinnedAlreadyExisting.length === 0) { - const savedPinnedEvent: SavedPinnedEvent = { - eventId, - timelineId, - }; - // create Pinned Event on Timeline - return convertSavedObjectToSavedPinnedEvent( - await savedObjectsClient.create( - pinnedEventSavedObjectType, - pickSavedPinnedEvent(pinnedEventId, savedPinnedEvent, request.user || null) - ), - timelineVersionSavedObject != null ? timelineVersionSavedObject : undefined - ); - } - return isPinnedAlreadyExisting[0]; + convertSavedObjectToSavedPinnedEvent: ( + savedObject: unknown, + timelineVersion?: string | undefined | null + ) => PinnedEventSavedObject; + + pickSavedPinnedEvent: ( + pinnedEventId: string | null, + savedPinnedEvent: SavedPinnedEvent, + userInfo: AuthenticatedUser | null + ) => // eslint-disable-next-line @typescript-eslint/no-explicit-any + any; +} + +export const deletePinnedEventOnTimeline = async ( + request: FrameworkRequest, + pinnedEventIds: string[] +) => { + const savedObjectsClient = request.context.core.savedObjects.client; + + await Promise.all( + pinnedEventIds.map(pinnedEventId => + savedObjectsClient.delete(pinnedEventSavedObjectType, pinnedEventId) + ) + ); +}; + +export const deleteAllPinnedEventsOnTimeline = async ( + request: FrameworkRequest, + timelineId: string +) => { + const savedObjectsClient = request.context.core.savedObjects.client; + const options: SavedObjectsFindOptions = { + type: pinnedEventSavedObjectType, + search: timelineId, + searchFields: ['timelineId'], + }; + const pinnedEventToBeDeleted = await getAllSavedPinnedEvents(request, options); + await Promise.all( + pinnedEventToBeDeleted.map(pinnedEvent => + savedObjectsClient.delete(pinnedEventSavedObjectType, pinnedEvent.pinnedEventId) + ) + ); +}; + +export const getPinnedEvent = async ( + request: FrameworkRequest, + pinnedEventId: string +): Promise => { + return getSavedPinnedEvent(request, pinnedEventId); +}; + +export const getAllPinnedEventsByTimelineId = async ( + request: FrameworkRequest, + timelineId: string +): Promise => { + const options: SavedObjectsFindOptions = { + type: pinnedEventSavedObjectType, + search: timelineId, + searchFields: ['timelineId'], + }; + return getAllSavedPinnedEvents(request, options); +}; + +export const getAllPinnedEvents = async ( + request: FrameworkRequest, + pageInfo: PageInfoNote | null, + search: string | null, + sort: SortNote | null +): Promise => { + const options: SavedObjectsFindOptions = { + type: pinnedEventSavedObjectType, + perPage: pageInfo != null ? pageInfo.pageSize : undefined, + page: pageInfo != null ? pageInfo.pageIndex : undefined, + search: search != null ? search : undefined, + searchFields: ['timelineId', 'eventId'], + sortField: sort != null ? sort.sortField : undefined, + sortOrder: sort != null ? sort.sortOrder : undefined, + }; + return getAllSavedPinnedEvents(request, options); +}; + +export const persistPinnedEventOnTimeline = async ( + request: FrameworkRequest, + pinnedEventId: string | null, // pinned event saved object id + eventId: string, + timelineId: string | null +): Promise => { + const savedObjectsClient = request.context.core.savedObjects.client; + + try { + if (pinnedEventId == null) { + const timelineVersionSavedObject = + timelineId == null + ? await (async () => { + const timelineResult = convertSavedObjectToSavedTimeline( + await savedObjectsClient.create( + timelineSavedObjectType, + pickSavedTimeline(null, {}, request.user || null) + ) + ); + timelineId = timelineResult.savedObjectId; // eslint-disable-line no-param-reassign + return timelineResult.version; + })() + : null; + + if (timelineId != null) { + const allPinnedEventId = await getAllPinnedEventsByTimelineId(request, timelineId); + const isPinnedAlreadyExisting = allPinnedEventId.filter( + pinnedEvent => pinnedEvent.eventId === eventId + ); + + if (isPinnedAlreadyExisting.length === 0) { + const savedPinnedEvent: SavedPinnedEvent = { + eventId, + timelineId, + }; + // create Pinned Event on Timeline + return convertSavedObjectToSavedPinnedEvent( + await savedObjectsClient.create( + pinnedEventSavedObjectType, + pickSavedPinnedEvent(pinnedEventId, savedPinnedEvent, request.user || null) + ), + timelineVersionSavedObject != null ? timelineVersionSavedObject : undefined + ); } - throw new Error('You can NOT pinned event without a timelineID'); + return isPinnedAlreadyExisting[0]; } - // Delete Pinned Event on Timeline - await this.deletePinnedEventOnTimeline(request, [pinnedEventId]); + throw new Error('You can NOT pinned event without a timelineID'); + } + // Delete Pinned Event on Timeline + await deletePinnedEventOnTimeline(request, [pinnedEventId]); + return null; + } catch (err) { + if (getOr(null, 'output.statusCode', err) === 404) { + /* + * Why we are doing that, because if it is not found for sure that it will be unpinned + * There is no need to bring back this error since we can assume that it is unpinned + */ return null; - } catch (err) { - if (getOr(null, 'output.statusCode', err) === 404) { - /* - * Why we are doing that, because if it is not found for sure that it will be unpinned - * There is no need to bring back this error since we can assume that it is unpinned - */ - return null; - } - if (getOr(null, 'output.statusCode', err) === 403) { - return pinnedEventId != null - ? { - code: 403, - message: err.message, - pinnedEventId: eventId, - timelineId: '', - timelineVersion: '', - } - : null; - } - throw err; } + if (getOr(null, 'output.statusCode', err) === 403) { + return pinnedEventId != null + ? { + code: 403, + message: err.message, + pinnedEventId: eventId, + timelineId: '', + timelineVersion: '', + } + : null; + } + throw err; } +}; - private async getSavedPinnedEvent(request: FrameworkRequest, pinnedEventId: string) { - const savedObjectsClient = request.context.core.savedObjects.client; - const savedObject = await savedObjectsClient.get(pinnedEventSavedObjectType, pinnedEventId); +const getSavedPinnedEvent = async (request: FrameworkRequest, pinnedEventId: string) => { + const savedObjectsClient = request.context.core.savedObjects.client; + const savedObject = await savedObjectsClient.get(pinnedEventSavedObjectType, pinnedEventId); - return convertSavedObjectToSavedPinnedEvent(savedObject); - } + return convertSavedObjectToSavedPinnedEvent(savedObject); +}; - private async getAllSavedPinnedEvents( - request: FrameworkRequest, - options: SavedObjectsFindOptions - ) { - const savedObjectsClient = request.context.core.savedObjects.client; - const savedObjects = await savedObjectsClient.find(options); - - return savedObjects.saved_objects.map(savedObject => - convertSavedObjectToSavedPinnedEvent(savedObject) - ); - } -} +const getAllSavedPinnedEvents = async ( + request: FrameworkRequest, + options: SavedObjectsFindOptions +) => { + const savedObjectsClient = request.context.core.savedObjects.client; + const savedObjects = await savedObjectsClient.find(options); + + return savedObjects.saved_objects.map(savedObject => + convertSavedObjectToSavedPinnedEvent(savedObject) + ); +}; export const convertSavedObjectToSavedPinnedEvent = ( savedObject: unknown, diff --git a/x-pack/plugins/siem/server/lib/timeline/convert_saved_object_to_savedtimeline.ts b/x-pack/plugins/siem/server/lib/timeline/convert_saved_object_to_savedtimeline.ts index ea5db565483c83..bde24a338ec846 100644 --- a/x-pack/plugins/siem/server/lib/timeline/convert_saved_object_to_savedtimeline.ts +++ b/x-pack/plugins/siem/server/lib/timeline/convert_saved_object_to_savedtimeline.ts @@ -8,16 +8,21 @@ import { failure } from 'io-ts/lib/PathReporter'; import { pipe } from 'fp-ts/lib/pipeable'; import { map, fold } from 'fp-ts/lib/Either'; import { identity } from 'fp-ts/lib/function'; -import { TimelineSavedObjectRuntimeType, TimelineSavedObject } from './types'; +import { + TimelineSavedObjectRuntimeType, + TimelineSavedObject, +} from '../../../common/types/timeline'; export const convertSavedObjectToSavedTimeline = (savedObject: unknown): TimelineSavedObject => { const timeline = pipe( TimelineSavedObjectRuntimeType.decode(savedObject), - map(savedTimeline => ({ - savedObjectId: savedTimeline.id, - version: savedTimeline.version, - ...savedTimeline.attributes, - })), + map(savedTimeline => { + return { + savedObjectId: savedTimeline.id, + version: savedTimeline.version, + ...savedTimeline.attributes, + }; + }), fold(errors => { throw new Error(failure(errors).join('\n')); }, identity) diff --git a/x-pack/plugins/siem/server/lib/timeline/create_timelines_stream_from_ndjson.ts b/x-pack/plugins/siem/server/lib/timeline/create_timelines_stream_from_ndjson.ts index abe8de9bf5b94b..6b4017b5e4d5c7 100644 --- a/x-pack/plugins/siem/server/lib/timeline/create_timelines_stream_from_ndjson.ts +++ b/x-pack/plugins/siem/server/lib/timeline/create_timelines_stream_from_ndjson.ts @@ -22,6 +22,7 @@ import { import { ImportTimelineResponse } from './routes/utils/import_timelines'; import { ImportTimelinesSchemaRt } from './routes/schemas/import_timelines_schema'; +import { BadRequestError } from '../detection_engine/errors/bad_request_error'; type ErrorFactory = (message: string) => Error; @@ -38,8 +39,11 @@ export const decodeOrThrow = ( pipe(runtimeType.decode(inputValue), fold(throwErrors(createError), identity)); export const validateTimelines = (): Transform => - createMapStream((obj: ImportTimelineResponse) => decodeOrThrow(ImportTimelinesSchemaRt)(obj)); - + createMapStream((obj: ImportTimelineResponse) => + obj instanceof Error + ? new BadRequestError(obj.message) + : decodeOrThrow(ImportTimelinesSchemaRt)(obj) + ); export const createTimelinesStreamFromNdJson = (ruleLimit: number) => { return [ createSplitStream('\n'), diff --git a/x-pack/plugins/siem/server/lib/timeline/pick_saved_timeline.ts b/x-pack/plugins/siem/server/lib/timeline/pick_saved_timeline.ts index 19adb7ac1045a0..eeded1cc2532de 100644 --- a/x-pack/plugins/siem/server/lib/timeline/pick_saved_timeline.ts +++ b/x-pack/plugins/siem/server/lib/timeline/pick_saved_timeline.ts @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import uuid from 'uuid'; import { AuthenticatedUser } from '../../../../security/common/model'; import { UNAUTHENTICATED_USER } from '../../../common/constants'; -import { SavedTimeline } from './types'; +import { SavedTimeline, TimelineType } from '../../../common/types/timeline'; export const pickSavedTimeline = ( timelineId: string | null, @@ -24,5 +25,21 @@ export const pickSavedTimeline = ( savedTimeline.updated = dateNow; savedTimeline.updatedBy = userInfo?.username ?? UNAUTHENTICATED_USER; } + + if (savedTimeline.timelineType === TimelineType.template) { + savedTimeline.timelineType = TimelineType.template; + if (savedTimeline.templateTimelineId == null) { + savedTimeline.templateTimelineId = uuid.v4(); + } + + if (savedTimeline.templateTimelineVersion == null) { + savedTimeline.templateTimelineVersion = 1; + } + } else { + savedTimeline.timelineType = TimelineType.default; + savedTimeline.templateTimelineId = null; + savedTimeline.templateTimelineVersion = null; + } + return savedTimeline; }; diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/README.md b/x-pack/plugins/siem/server/lib/timeline/routes/README.md new file mode 100644 index 00000000000000..2c5547e39fc4e5 --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/README.md @@ -0,0 +1,326 @@ +**Timeline apis** + + 1. Create timeline api + 2. Update timeline api + 3. Create template timeline api + 4. Update template timeline api + + +## Create timeline api +#### POST /api/timeline +##### Authorization +Type: Basic Auth +username: Your Kibana username +password: Your Kibana password + + +##### Request header +``` +Content-Type: application/json +kbn-version: 8.0.0 +``` +##### Request body +```json +{ + "timeline": { + "columns": [ + { + "columnHeaderType": "not-filtered", + "id": "@timestamp" + }, + { + "columnHeaderType": "not-filtered", + "id": "message" + }, + { + "columnHeaderType": "not-filtered", + "id": "event.category" + }, + { + "columnHeaderType": "not-filtered", + "id": "event.action" + }, + { + "columnHeaderType": "not-filtered", + "id": "host.name" + }, + { + "columnHeaderType": "not-filtered", + "id": "source.ip" + }, + { + "columnHeaderType": "not-filtered", + "id": "destination.ip" + }, + { + "columnHeaderType": "not-filtered", + "id": "user.name" + } + ], + "dataProviders": [], + "description": "", + "eventType": "all", + "filters": [], + "kqlMode": "filter", + "kqlQuery": { + "filterQuery": null + }, + "title": "abd", + "dateRange": { + "start": 1587370079200, + "end": 1587456479201 + }, + "savedQueryId": null, + "sort": { + "columnId": "@timestamp", + "sortDirection": "desc" + } + }, + "timelineId":null, // Leave this as null + "version":null // Leave this as null +} +``` + + +## Update timeline api +#### PATCH /api/timeline +##### Authorization +Type: Basic Auth +username: Your Kibana username +password: Your Kibana password + + +##### Request header +``` +Content-Type: application/json +kbn-version: 8.0.0 +``` +##### Request body +```json +{ + "timeline": { + "columns": [ + { + "columnHeaderType": "not-filtered", + "id": "@timestamp" + }, + { + "columnHeaderType": "not-filtered", + "id": "message" + }, + { + "columnHeaderType": "not-filtered", + "id": "event.category" + }, + { + "columnHeaderType": "not-filtered", + "id": "event.action" + }, + { + "columnHeaderType": "not-filtered", + "id": "host.name" + }, + { + "columnHeaderType": "not-filtered", + "id": "source.ip" + }, + { + "columnHeaderType": "not-filtered", + "id": "destination.ip" + }, + { + "columnHeaderType": "not-filtered", + "id": "user.name" + } + ], + "dataProviders": [], + "description": "", + "eventType": "all", + "filters": [], + "kqlMode": "filter", + "kqlQuery": { + "filterQuery": null + }, + "title": "abd", + "dateRange": { + "start": 1587370079200, + "end": 1587456479201 + }, + "savedQueryId": null, + "sort": { + "columnId": "@timestamp", + "sortDirection": "desc" + }, + "created": 1587468588922, + "createdBy": "casetester", + "updated": 1587468588922, + "updatedBy": "casetester", + "timelineType": "default" + }, + "timelineId":"68ea5330-83c3-11ea-bff9-ab01dd7cb6cc", // Have to match the existing timeline savedObject id + "version":"WzYwLDFd" // Have to match the existing timeline version +} +``` + +## Create template timeline api +#### POST /api/timeline +##### Authorization +Type: Basic Auth +username: Your Kibana username +password: Your Kibana password + + +##### Request header +``` +Content-Type: application/json +kbn-version: 8.0.0 +``` +##### Request body +```json +{ + "timeline": { + "columns": [ + { + "columnHeaderType": "not-filtered", + "id": "@timestamp" + }, + { + "columnHeaderType": "not-filtered", + "id": "message" + }, + { + "columnHeaderType": "not-filtered", + "id": "event.category" + }, + { + "columnHeaderType": "not-filtered", + "id": "event.action" + }, + { + "columnHeaderType": "not-filtered", + "id": "host.name" + }, + { + "columnHeaderType": "not-filtered", + "id": "source.ip" + }, + { + "columnHeaderType": "not-filtered", + "id": "destination.ip" + }, + { + "columnHeaderType": "not-filtered", + "id": "user.name" + } + ], + "dataProviders": [ + + ], + "description": "", + "eventType": "all", + "filters": [ + + ], + "kqlMode": "filter", + "kqlQuery": { + "filterQuery": null + }, + "title": "abd", + "dateRange": { + "start": 1587370079200, + "end": 1587456479201 + }, + "savedQueryId": null, + "sort": { + "columnId": "@timestamp", + "sortDirection": "desc" + }, + "timelineType": "template" // This is the difference between create timeline + }, + "timelineId":null, // Leave this as null + "version":null // Leave this as null +} +``` + + +## Update template timeline api +#### PATCH /api/timeline +##### Authorization +Type: Basic Auth +username: Your Kibana username +password: Your Kibana password + + +##### Request header +``` +Content-Type: application/json +kbn-version: 8.0.0 +``` +##### Request body +```json +{ + "timeline": { + "columns": [ + { + "columnHeaderType": "not-filtered", + "id": "@timestamp" + }, + { + "columnHeaderType": "not-filtered", + "id": "message" + }, + { + "columnHeaderType": "not-filtered", + "id": "event.category" + }, + { + "columnHeaderType": "not-filtered", + "id": "event.action" + }, + { + "columnHeaderType": "not-filtered", + "id": "host.name" + }, + { + "columnHeaderType": "not-filtered", + "id": "source.ip" + }, + { + "columnHeaderType": "not-filtered", + "id": "destination.ip" + }, + { + "columnHeaderType": "not-filtered", + "id": "user.name" + } + ], + "dataProviders": [], + "description": "", + "eventType": "all", + "filters": [], + "kqlMode": "filter", + "kqlQuery": { + "filterQuery": null + }, + "title": "abd", + "dateRange": { + "start": 1587370079200, + "end": 1587456479201 + }, + "savedQueryId": null, + "sort": { + "columnId": "@timestamp", + "sortDirection": "desc" + }, + "timelineType": "template", + "created": 1587473119992, + "createdBy": "casetester", + "updated": 1587473119992, + "updatedBy": "casetester", + "templateTimelineId": "745d0316-6af7-43bf-afd6-9747119754fb", // Please provide the existing template timeline version + "templateTimelineVersion": 2 // Please provide a template timeline version grater than existing one + }, + "timelineId":"f5a4bd10-83cd-11ea-bf78-0547a65f1281", // This is a must as well + "version":"Wzg2LDFd" // Please provide the existing timeline version +} +``` \ No newline at end of file diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/import_timelines.ts b/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/import_timelines.ts index 686f2b491cf881..a832c818d48b07 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/import_timelines.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/import_timelines.ts @@ -5,6 +5,7 @@ */ import { omit } from 'lodash/fp'; +import { TimelineType } from '../../../../../common/types/timeline'; export const mockDuplicateIdErrors = []; @@ -148,6 +149,13 @@ export const mockGetTimelineValue = { pinnedEventIds: ['k-gi8nABm-sIqJ_scOoS'], }; +export const mockGetTemplateTimelineValue = { + ...mockGetTimelineValue, + timelineType: TimelineType.template, + templateTimelineId: '79deb4c0-6bc1-11ea-a90b-f5341fb7a189', + templateTimelineVersion: 1, +}; + export const mockParsedTimelineObject = omit( [ 'globalNotes', diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/request_responses.ts b/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/request_responses.ts index a83c4437733021..304ca309775ff8 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/__mocks__/request_responses.ts @@ -3,10 +3,18 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - -import { TIMELINE_EXPORT_URL, TIMELINE_IMPORT_URL } from '../../../../../common/constants'; -import { requestMock } from '../../../detection_engine/routes/__mocks__'; +import * as rt from 'io-ts'; +import { + TIMELINE_EXPORT_URL, + TIMELINE_IMPORT_URL, + TIMELINE_URL, +} from '../../../../../common/constants'; import stream from 'stream'; +import { requestMock } from '../../../detection_engine/routes/__mocks__'; +import { SavedTimeline, TimelineType } from '../../../../../common/types/timeline'; +import { updateTimelineSchema } from '../schemas/update_timelines_schema'; +import { createTimelineSchema } from '../schemas/create_timelines_schema'; + const readable = new stream.Readable(); export const getExportTimelinesRequest = () => requestMock.create({ @@ -31,6 +39,96 @@ export const getImportTimelinesRequest = (filename?: string) => }, }); +export const inputTimeline: SavedTimeline = { + columns: [ + { columnHeaderType: 'not-filtered', id: '@timestamp' }, + { columnHeaderType: 'not-filtered', id: 'message' }, + { columnHeaderType: 'not-filtered', id: 'event.category' }, + { columnHeaderType: 'not-filtered', id: 'event.action' }, + { columnHeaderType: 'not-filtered', id: 'host.name' }, + { columnHeaderType: 'not-filtered', id: 'source.ip' }, + { columnHeaderType: 'not-filtered', id: 'destination.ip' }, + { columnHeaderType: 'not-filtered', id: 'user.name' }, + ], + dataProviders: [], + description: '', + eventType: 'all', + filters: [], + kqlMode: 'filter', + kqlQuery: { filterQuery: null }, + title: 't', + timelineType: TimelineType.default, + templateTimelineId: null, + templateTimelineVersion: null, + dateRange: { start: 1585227005527, end: 1585313405527 }, + savedQueryId: null, + sort: { columnId: '@timestamp', sortDirection: 'desc' }, +}; + +export const inputTemplateTimeline = { + ...inputTimeline, + timelineType: TimelineType.template, + templateTimelineId: null, + templateTimelineVersion: null, +}; + +export const createTimelineWithoutTimelineId = { + templateTimelineId: null, + timeline: inputTimeline, + timelineId: null, + version: null, + timelineType: TimelineType.default, +}; + +export const createTemplateTimelineWithoutTimelineId = { + templateTimelineId: null, + timeline: inputTemplateTimeline, + timelineId: null, + version: null, + timelineType: TimelineType.template, +}; + +export const createTimelineWithTimelineId = { + ...createTimelineWithoutTimelineId, + timelineId: '79deb4c0-6bc1-11ea-a90b-f5341fb7a189', +}; + +export const createTemplateTimelineWithTimelineId = { + ...createTemplateTimelineWithoutTimelineId, + timelineId: '79deb4c0-6bc1-11ea-a90b-f5341fb7a189', + templateTimelineId: 'existing template timeline id', +}; + +export const updateTimelineWithTimelineId = { + timeline: inputTimeline, + timelineId: '79deb4c0-6bc1-11ea-a90b-f5341fb7a189', + version: 'WzEyMjUsMV0=', +}; + +export const updateTemplateTimelineWithTimelineId = { + timeline: { + ...inputTemplateTimeline, + templateTimelineId: '79deb4c0-6bc1-11ea-a90b-f5341fb7a189', + templateTimelineVersion: 2, + }, + timelineId: '79deb4c0-6bc1-11ea-a90b-f5341fb7a189', + version: 'WzEyMjUsMV0=', +}; + +export const getCreateTimelinesRequest = (mockBody: rt.TypeOf) => + requestMock.create({ + method: 'post', + path: TIMELINE_URL, + body: mockBody, + }); + +export const getUpdateTimelinesRequest = (mockBody: rt.TypeOf) => + requestMock.create({ + method: 'patch', + path: TIMELINE_URL, + body: mockBody, + }); + export const getImportTimelinesRequestEnableOverwrite = (filename?: string) => requestMock.create({ method: 'post', diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/create_timelines_route.test.ts b/x-pack/plugins/siem/server/lib/timeline/routes/create_timelines_route.test.ts new file mode 100644 index 00000000000000..70ee1532395a5d --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/create_timelines_route.test.ts @@ -0,0 +1,272 @@ +/* + * 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 { SecurityPluginSetup } from '../../../../../../plugins/security/server'; + +import { + serverMock, + requestContextMock, + createMockConfig, +} from '../../detection_engine/routes/__mocks__'; + +import { + mockGetCurrentUser, + mockGetTimelineValue, + mockGetTemplateTimelineValue, +} from './__mocks__/import_timelines'; +import { + getCreateTimelinesRequest, + inputTimeline, + createTimelineWithoutTimelineId, + createTimelineWithTimelineId, + createTemplateTimelineWithoutTimelineId, + createTemplateTimelineWithTimelineId, +} from './__mocks__/request_responses'; +import { + CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + CREATE_TIMELINE_ERROR_MESSAGE, +} from './utils/create_timelines'; + +describe('create timelines', () => { + let server: ReturnType; + let securitySetup: SecurityPluginSetup; + let { context } = requestContextMock.createTools(); + let mockGetTimeline: jest.Mock; + let mockPersistTimeline: jest.Mock; + let mockPersistPinnedEventOnTimeline: jest.Mock; + let mockPersistNote: jest.Mock; + + beforeEach(() => { + jest.resetModules(); + jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); + + server = serverMock.create(); + context = requestContextMock.createTools().context; + + securitySetup = ({ + authc: { + getCurrentUser: jest.fn().mockReturnValue(mockGetCurrentUser), + }, + authz: {}, + } as unknown) as SecurityPluginSetup; + + mockGetTimeline = jest.fn(); + mockPersistTimeline = jest.fn(); + mockPersistPinnedEventOnTimeline = jest.fn(); + mockPersistNote = jest.fn(); + }); + + describe('Manipulate timeline', () => { + describe('Create a new timeline', () => { + beforeEach(async () => { + jest.doMock('../saved_object', () => { + return { + getTimeline: mockGetTimeline.mockReturnValue(null), + persistTimeline: mockPersistTimeline.mockReturnValue({ + timeline: createTimelineWithTimelineId, + }), + }; + }); + + jest.doMock('../../pinned_event/saved_object', () => { + return { + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, + }; + }); + + jest.doMock('../../note/saved_object', () => { + return { + persistNote: mockPersistNote, + }; + }); + + const createTimelinesRoute = jest.requireActual('./create_timelines_route') + .createTimelinesRoute; + createTimelinesRoute(server.router, createMockConfig(), securitySetup); + + const mockRequest = getCreateTimelinesRequest(createTimelineWithoutTimelineId); + await server.inject(mockRequest, context); + }); + + test('should Create a new timeline savedObject', async () => { + expect(mockPersistTimeline).toHaveBeenCalled(); + }); + + test('should Create a new timeline savedObject without timelineId', async () => { + expect(mockPersistTimeline.mock.calls[0][1]).toBeNull(); + }); + + test('should Create a new timeline savedObject without timeline version', async () => { + expect(mockPersistTimeline.mock.calls[0][2]).toBeNull(); + }); + + test('should Create a new timeline savedObject witn given timeline', async () => { + expect(mockPersistTimeline.mock.calls[0][3]).toEqual(inputTimeline); + }); + + test('should NOT Create new pinned events', async () => { + expect(mockPersistPinnedEventOnTimeline).not.toBeCalled(); + }); + + test('should NOT Create notes', async () => { + expect(mockPersistNote).not.toBeCalled(); + }); + + test('returns 200 when create timeline successfully', async () => { + const response = await server.inject( + getCreateTimelinesRequest(createTimelineWithoutTimelineId), + context + ); + expect(response.status).toEqual(200); + }); + }); + + describe('Import a timeline already exist', () => { + beforeEach(() => { + jest.doMock('../saved_object', () => { + return { + getTimeline: mockGetTimeline.mockReturnValue(mockGetTimelineValue), + persistTimeline: mockPersistTimeline, + }; + }); + + jest.doMock('../../pinned_event/saved_object', () => { + return { + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, + }; + }); + + jest.doMock('../../note/saved_object', () => { + return { + persistNote: mockPersistNote, + }; + }); + + const createTimelinesRoute = jest.requireActual('./create_timelines_route') + .createTimelinesRoute; + createTimelinesRoute(server.router, createMockConfig(), securitySetup); + }); + + test('returns error message', async () => { + const response = await server.inject( + getCreateTimelinesRequest(createTimelineWithTimelineId), + context + ); + expect(response.body).toEqual({ + message: CREATE_TIMELINE_ERROR_MESSAGE, + status_code: 405, + }); + }); + }); + }); + + describe('Manipulate template timeline', () => { + describe('Create a new template timeline', () => { + beforeEach(async () => { + jest.doMock('../saved_object', () => { + return { + getTimeline: mockGetTimeline.mockReturnValue(null), + persistTimeline: mockPersistTimeline.mockReturnValue({ + timeline: createTemplateTimelineWithTimelineId, + }), + }; + }); + + jest.doMock('../../pinned_event/saved_object', () => { + return { + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, + }; + }); + + jest.doMock('../../note/saved_object', () => { + return { + persistNote: mockPersistNote, + }; + }); + + const createTimelinesRoute = jest.requireActual('./create_timelines_route') + .createTimelinesRoute; + createTimelinesRoute(server.router, createMockConfig(), securitySetup); + + const mockRequest = getCreateTimelinesRequest(createTemplateTimelineWithoutTimelineId); + await server.inject(mockRequest, context); + }); + + test('should Create a new template timeline savedObject', async () => { + expect(mockPersistTimeline).toHaveBeenCalled(); + }); + + test('should Create a new template timeline savedObject without timelineId', async () => { + expect(mockPersistTimeline.mock.calls[0][1]).toBeNull(); + }); + + test('should Create a new template timeline savedObject without template timeline version', async () => { + expect(mockPersistTimeline.mock.calls[0][2]).toBeNull(); + }); + + test('should Create a new template timeline savedObject witn given template timeline', async () => { + expect(mockPersistTimeline.mock.calls[0][3]).toEqual( + createTemplateTimelineWithTimelineId.timeline + ); + }); + + test('should NOT Create new pinned events', async () => { + expect(mockPersistPinnedEventOnTimeline).not.toBeCalled(); + }); + + test('should NOT Create notes', async () => { + expect(mockPersistNote).not.toBeCalled(); + }); + + test('returns 200 when create timeline successfully', async () => { + const response = await server.inject( + getCreateTimelinesRequest(createTimelineWithoutTimelineId), + context + ); + expect(response.status).toEqual(200); + }); + }); + + describe('Import a template timeline already exist', () => { + beforeEach(() => { + jest.doMock('../saved_object', () => { + return { + getTimeline: mockGetTimeline.mockReturnValue(mockGetTemplateTimelineValue), + persistTimeline: mockPersistTimeline, + }; + }); + + jest.doMock('../../pinned_event/saved_object', () => { + return { + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, + }; + }); + + jest.doMock('../../note/saved_object', () => { + return { + persistNote: mockPersistNote, + }; + }); + + const createTimelinesRoute = jest.requireActual('./create_timelines_route') + .createTimelinesRoute; + createTimelinesRoute(server.router, createMockConfig(), securitySetup); + }); + + test('returns error message', async () => { + const response = await server.inject( + getCreateTimelinesRequest(createTemplateTimelineWithTimelineId), + context + ); + expect(response.body).toEqual({ + message: CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + status_code: 405, + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/create_timelines_route.ts b/x-pack/plugins/siem/server/lib/timeline/routes/create_timelines_route.ts new file mode 100644 index 00000000000000..c456ae31fb7da6 --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/create_timelines_route.ts @@ -0,0 +1,90 @@ +/* + * 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 { IRouter } from '../../../../../../../src/core/server'; + +import { TIMELINE_URL } from '../../../../common/constants'; +import { TimelineType } from '../../../../common/types/timeline'; + +import { ConfigType } from '../../..'; +import { SetupPlugins } from '../../../plugin'; +import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; + +import { transformError, buildSiemResponse } from '../../detection_engine/routes/utils'; + +import { createTimelineSchema } from './schemas/create_timelines_schema'; +import { buildFrameworkRequest } from './utils/common'; +import { + createTimelines, + getTimeline, + getTemplateTimeline, + CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + CREATE_TIMELINE_ERROR_MESSAGE, +} from './utils/create_timelines'; + +export const createTimelinesRoute = ( + router: IRouter, + config: ConfigType, + security: SetupPlugins['security'] +) => { + router.post( + { + path: TIMELINE_URL, + validate: { + body: buildRouteValidation(createTimelineSchema), + }, + options: { + tags: ['access:siem'], + }, + }, + async (context, request, response) => { + const siemResponse = buildSiemResponse(response); + + try { + const frameworkRequest = await buildFrameworkRequest(context, security, request); + + const { timelineId, timeline, version } = request.body; + const { templateTimelineId, timelineType } = timeline; + const isHandlingTemplateTimeline = timelineType === TimelineType.template; + + const existTimeline = + timelineId != null ? await getTimeline(frameworkRequest, timelineId) : null; + const existTemplateTimeline = + templateTimelineId != null + ? await getTemplateTimeline(frameworkRequest, templateTimelineId) + : null; + + if ( + (!isHandlingTemplateTimeline && existTimeline != null) || + (isHandlingTemplateTimeline && (existTemplateTimeline != null || existTimeline != null)) + ) { + return siemResponse.error({ + body: isHandlingTemplateTimeline + ? CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE + : CREATE_TIMELINE_ERROR_MESSAGE, + statusCode: 405, + }); + } + + // Create timeline + const newTimeline = await createTimelines(frameworkRequest, timeline, null, version); + return response.ok({ + body: { + data: { + persistTimeline: newTimeline, + }, + }, + }); + } catch (err) { + const error = transformError(err); + + return siemResponse.error({ + body: error.message, + statusCode: error.statusCode, + }); + } + } + ); +}; diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts index 9f41943cfa27f7..56c152d02ae98d 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.test.ts @@ -6,13 +6,13 @@ import { getImportTimelinesRequest } from './__mocks__/request_responses'; import { - createMockConfig, serverMock, requestContextMock, requestMock, + createMockConfig, } from '../../detection_engine/routes/__mocks__'; import { TIMELINE_EXPORT_URL } from '../../../../common/constants'; -import { SecurityPluginSetup } from '../../../../../security/server'; +import { SecurityPluginSetup } from '../../../../../../plugins/security/server'; import { mockUniqueParsedObjects, @@ -24,7 +24,6 @@ import { } from './__mocks__/import_timelines'; describe('import timelines', () => { - let config: ReturnType; let server: ReturnType; let request: ReturnType; let securitySetup: SecurityPluginSetup; @@ -43,7 +42,6 @@ describe('import timelines', () => { server = serverMock.create(); context = requestContextMock.createTools().context; - config = createMockConfig(); securitySetup = ({ authc: { @@ -84,40 +82,28 @@ describe('import timelines', () => { beforeEach(() => { jest.doMock('../saved_object', () => { return { - Timeline: jest.fn().mockImplementation(() => { - return { - getTimeline: mockGetTimeline.mockReturnValue(null), - persistTimeline: mockPersistTimeline.mockReturnValue({ - timeline: { savedObjectId: newTimelineSavedObjectId, version: newTimelineVersion }, - }), - }; + getTimeline: mockGetTimeline.mockReturnValue(null), + persistTimeline: mockPersistTimeline.mockReturnValue({ + timeline: { savedObjectId: newTimelineSavedObjectId, version: newTimelineVersion }, }), }; }); jest.doMock('../../pinned_event/saved_object', () => { return { - PinnedEvent: jest.fn().mockImplementation(() => { - return { - persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, - }; - }), + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, }; }); jest.doMock('../../note/saved_object', () => { return { - Note: jest.fn().mockImplementation(() => { - return { - persistNote: mockPersistNote, - }; - }), + persistNote: mockPersistNote, }; }); const importTimelinesRoute = jest.requireActual('./import_timelines_route') .importTimelinesRoute; - importTimelinesRoute(server.router, config, securitySetup); + importTimelinesRoute(server.router, createMockConfig(), securitySetup); }); test('should use given timelineId to check if the timeline savedObject already exist', async () => { @@ -230,38 +216,26 @@ describe('import timelines', () => { beforeEach(() => { jest.doMock('../saved_object', () => { return { - Timeline: jest.fn().mockImplementation(() => { - return { - getTimeline: mockGetTimeline.mockReturnValue(mockGetTimelineValue), - persistTimeline: mockPersistTimeline, - }; - }), + getTimeline: mockGetTimeline.mockReturnValue(mockGetTimelineValue), + persistTimeline: mockPersistTimeline, }; }); jest.doMock('../../pinned_event/saved_object', () => { return { - PinnedEvent: jest.fn().mockImplementation(() => { - return { - persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, - }; - }), + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, }; }); jest.doMock('../../note/saved_object', () => { return { - Note: jest.fn().mockImplementation(() => { - return { - persistNote: mockPersistNote, - }; - }), + persistNote: mockPersistNote, }; }); const importTimelinesRoute = jest.requireActual('./import_timelines_route') .importTimelinesRoute; - importTimelinesRoute(server.router, config, securitySetup); + importTimelinesRoute(server.router, createMockConfig(), securitySetup); }); test('returns error message', async () => { @@ -286,36 +260,24 @@ describe('import timelines', () => { beforeEach(() => { jest.doMock('../saved_object', () => { return { - Timeline: jest.fn().mockImplementation(() => { - return { - getTimeline: mockGetTimeline.mockReturnValue(null), - persistTimeline: mockPersistTimeline.mockReturnValue({ - timeline: { savedObjectId: '79deb4c0-6bc1-11ea-9999-f5341fb7a189' }, - }), - }; + getTimeline: mockGetTimeline.mockReturnValue(null), + persistTimeline: mockPersistTimeline.mockReturnValue({ + timeline: { savedObjectId: '79deb4c0-6bc1-11ea-9999-f5341fb7a189' }, }), }; }); jest.doMock('../../pinned_event/saved_object', () => { return { - PinnedEvent: jest.fn().mockImplementation(() => { - return { - persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline.mockReturnValue( - new Error('Test error') - ), - }; - }), + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline.mockReturnValue( + new Error('Test error') + ), }; }); jest.doMock('../../note/saved_object', () => { return { - Note: jest.fn().mockImplementation(() => { - return { - persistNote: mockPersistNote, - }; - }), + persistNote: mockPersistNote, }; }); }); @@ -328,11 +290,14 @@ describe('import timelines', () => { const importTimelinesRoute = jest.requireActual('./import_timelines_route') .importTimelinesRoute; - importTimelinesRoute(server.router, config, securitySetup); + importTimelinesRoute(server.router, createMockConfig(), securitySetup); const result = server.validate(request); expect(result.badRequest).toHaveBeenCalledWith( - 'Invalid value "undefined" supplied to "file",Invalid value "undefined" supplied to "file"' + [ + 'Invalid value "undefined" supplied to "file"', + 'Invalid value "undefined" supplied to "file"', + ].join(',') ); }); }); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.ts b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.ts index 9d148abf82cddd..bff89bdf9b5b21 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/import_timelines_route.ts @@ -5,9 +5,19 @@ */ import { extname } from 'path'; -import { chunk, omit, set } from 'lodash/fp'; +import { chunk, omit } from 'lodash/fp'; + +import { createPromiseFromStreams } from '../../../../../../../src/legacy/utils'; +import { IRouter } from '../../../../../../../src/core/server'; import { TIMELINE_IMPORT_URL } from '../../../../common/constants'; + +import { SetupPlugins } from '../../../plugin'; +import { ConfigType } from '../../../config'; +import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; + +import { importRulesSchema } from '../../detection_engine/routes/schemas/response/import_rules_schema'; +import { validate } from '../../detection_engine/routes/rules/validate'; import { buildSiemResponse, createBulkErrorObject, @@ -16,32 +26,22 @@ import { } from '../../detection_engine/routes/utils'; import { createTimelinesStreamFromNdJson } from '../create_timelines_stream_from_ndjson'; -import { createPromiseFromStreams } from '../../../../../../../src/legacy/utils'; +import { ImportTimelinesPayloadSchemaRt } from './schemas/import_timelines_schema'; +import { buildFrameworkRequest } from './utils/common'; import { - createTimelines, getTupleDuplicateErrorsAndUniqueTimeline, isBulkError, isImportRegular, ImportTimelineResponse, ImportTimelinesSchema, PromiseFromStreams, + timelineSavedObjectOmittedFields, } from './utils/import_timelines'; +import { createTimelines, getTimeline } from './utils/create_timelines'; -import { IRouter } from '../../../../../../../src/core/server'; -import { SetupPlugins } from '../../../plugin'; -import { ImportTimelinesPayloadSchemaRt } from './schemas/import_timelines_schema'; -import { importRulesSchema } from '../../detection_engine/routes/schemas/response/import_rules_schema'; -import { ConfigType } from '../../../config'; - -import { Timeline } from '../saved_object'; -import { validate } from '../../detection_engine/routes/rules/validate'; -import { FrameworkRequest } from '../../framework'; -import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; const CHUNK_PARSED_OBJECT_SIZE = 10; -const timelineLib = new Timeline(); - export const importTimelinesRoute = ( router: IRouter, config: ConfigType, @@ -95,9 +95,7 @@ export const importTimelinesRoute = ( const chunkParseObjects = chunk(CHUNK_PARSED_OBJECT_SIZE, uniqueParsedObjects); let importTimelineResponse: ImportTimelineResponse[] = []; - const user = await security?.authc.getCurrentUser(request); - let frameworkRequest = set('context.core.savedObjects.client', savedObjectsClient, request); - frameworkRequest = set('user', user, frameworkRequest); + const frameworkRequest = await buildFrameworkRequest(context, security, request); while (chunkParseObjects.length) { const batchParseObjects = chunkParseObjects.shift() ?? []; @@ -125,32 +123,16 @@ export const importTimelinesRoute = ( eventNotes, } = parsedTimeline; const parsedTimelineObject = omit( - [ - 'globalNotes', - 'eventNotes', - 'pinnedEventIds', - 'version', - 'savedObjectId', - 'created', - 'createdBy', - 'updated', - 'updatedBy', - ], + timelineSavedObjectOmittedFields, parsedTimeline ); + let newTimeline = null; try { - let timeline = null; - try { - timeline = await timelineLib.getTimeline( - (frameworkRequest as unknown) as FrameworkRequest, - savedObjectId - ); - // eslint-disable-next-line no-empty - } catch (e) {} + const timeline = await getTimeline(frameworkRequest, savedObjectId); if (timeline == null) { - const newSavedObjectId = await createTimelines( - (frameworkRequest as unknown) as FrameworkRequest, + newTimeline = await createTimelines( + frameworkRequest, parsedTimelineObject, null, // timelineSavedObjectId null, // timelineVersion @@ -159,7 +141,10 @@ export const importTimelinesRoute = ( [] // existing note ids ); - resolve({ timeline_id: newSavedObjectId, status_code: 200 }); + resolve({ + timeline_id: newTimeline.timeline.savedObjectId, + status_code: 200, + }); } else { resolve( createBulkErrorObject({ diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/schemas/create_timelines_schema.ts b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/create_timelines_schema.ts new file mode 100644 index 00000000000000..241d266a14c78f --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/create_timelines_schema.ts @@ -0,0 +1,19 @@ +/* + * 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 * as rt from 'io-ts'; + +import { SavedTimelineRuntimeType } from '../../../../../common/types/timeline'; +import { unionWithNullType } from '../../../../../common/utility_types'; + +export const createTimelineSchema = rt.intersection([ + rt.type({ + timeline: SavedTimelineRuntimeType, + }), + rt.partial({ + timelineId: unionWithNullType(rt.string), + version: unionWithNullType(rt.string), + }), +]); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/schemas/import_timelines_schema.ts b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/import_timelines_schema.ts index 056fdaf0d2515f..3b340b1c15359f 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/schemas/import_timelines_schema.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/import_timelines_schema.ts @@ -7,14 +7,17 @@ import * as rt from 'io-ts'; import { Readable } from 'stream'; import { either } from 'fp-ts/lib/Either'; + +import { SavedTimelineRuntimeType } from '../../../../../common/types/timeline'; + import { eventNotes, globalNotes, pinnedEventIds } from './schemas'; -import { SavedTimelineRuntimeType } from '../../types'; +import { unionWithNullType } from '../../../../../common/utility_types'; export const ImportTimelinesSchemaRt = rt.intersection([ SavedTimelineRuntimeType, rt.type({ - savedObjectId: rt.string, - version: rt.string, + savedObjectId: unionWithNullType(rt.string), + version: unionWithNullType(rt.string), }), rt.type({ globalNotes, diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/schemas/schemas.ts b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/schemas.ts index 71627363ef0f88..1fd3a3554dc155 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/schemas/schemas.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/schemas.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ import * as runtimeTypes from 'io-ts'; -import { unionWithNullType } from '../../../framework'; -import { SavedNoteRuntimeType } from '../../../note/types'; +import { unionWithNullType } from '../../../../../common/utility_types'; +import { SavedNoteRuntimeType } from '../../../../../common/types/timeline/note'; -export const eventNotes = runtimeTypes.array(unionWithNullType(SavedNoteRuntimeType)); -export const globalNotes = runtimeTypes.array(unionWithNullType(SavedNoteRuntimeType)); -export const pinnedEventIds = runtimeTypes.array(unionWithNullType(runtimeTypes.string)); +export const eventNotes = unionWithNullType(runtimeTypes.array(SavedNoteRuntimeType)); +export const globalNotes = unionWithNullType(runtimeTypes.array(SavedNoteRuntimeType)); +export const pinnedEventIds = unionWithNullType(runtimeTypes.array(runtimeTypes.string)); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/schemas/update_timelines_schema.ts b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/update_timelines_schema.ts new file mode 100644 index 00000000000000..43f4208947aa50 --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/schemas/update_timelines_schema.ts @@ -0,0 +1,16 @@ +/* + * 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 * as rt from 'io-ts'; + +import { SavedTimelineRuntimeType } from '../../../../../common/types/timeline'; +import { unionWithNullType } from '../../../../../common/utility_types'; + +export const updateTimelineSchema = rt.type({ + timeline: SavedTimelineRuntimeType, + timelineId: unionWithNullType(rt.string), + version: unionWithNullType(rt.string), +}); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/update_timelines_route.test.ts b/x-pack/plugins/siem/server/lib/timeline/routes/update_timelines_route.test.ts new file mode 100644 index 00000000000000..9c47488d47159a --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/update_timelines_route.test.ts @@ -0,0 +1,288 @@ +/* + * 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 { SecurityPluginSetup } from '../../../../../../plugins/security/server'; + +import { + serverMock, + requestContextMock, + createMockConfig, +} from '../../detection_engine/routes/__mocks__'; + +import { + getUpdateTimelinesRequest, + inputTimeline, + updateTimelineWithTimelineId, + updateTemplateTimelineWithTimelineId, +} from './__mocks__/request_responses'; +import { + mockGetCurrentUser, + mockGetTimelineValue, + mockGetTemplateTimelineValue, +} from './__mocks__/import_timelines'; +import { + UPDATE_TIMELINE_ERROR_MESSAGE, + UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, +} from './utils/update_timelines'; + +describe('update timelines', () => { + let server: ReturnType; + let securitySetup: SecurityPluginSetup; + let { context } = requestContextMock.createTools(); + let mockGetTimeline: jest.Mock; + let mockGetTemplateTimeline: jest.Mock; + let mockPersistTimeline: jest.Mock; + let mockPersistPinnedEventOnTimeline: jest.Mock; + let mockPersistNote: jest.Mock; + + beforeEach(() => { + jest.resetModules(); + jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); + + server = serverMock.create(); + context = requestContextMock.createTools().context; + + securitySetup = ({ + authc: { + getCurrentUser: jest.fn().mockReturnValue(mockGetCurrentUser), + }, + authz: {}, + } as unknown) as SecurityPluginSetup; + + mockGetTimeline = jest.fn(); + mockGetTemplateTimeline = jest.fn(); + mockPersistTimeline = jest.fn(); + mockPersistPinnedEventOnTimeline = jest.fn(); + mockPersistNote = jest.fn(); + }); + + describe('Manipulate timeline', () => { + describe('Update an existing timeline', () => { + beforeEach(async () => { + jest.doMock('../saved_object', () => { + return { + getTimeline: mockGetTimeline.mockReturnValue(mockGetTimelineValue), + persistTimeline: mockPersistTimeline.mockReturnValue({ + timeline: updateTimelineWithTimelineId.timeline, + }), + }; + }); + + jest.doMock('../../pinned_event/saved_object', () => { + return { + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, + }; + }); + + jest.doMock('../../note/saved_object', () => { + return { + persistNote: mockPersistNote, + }; + }); + + const updateTimelinesRoute = jest.requireActual('./update_timelines_route') + .updateTimelinesRoute; + updateTimelinesRoute(server.router, createMockConfig(), securitySetup); + + const mockRequest = getUpdateTimelinesRequest(updateTimelineWithTimelineId); + await server.inject(mockRequest, context); + }); + + test('should Check a if given timeline id exist', async () => { + expect(mockGetTimeline.mock.calls[0][1]).toEqual(updateTimelineWithTimelineId.timelineId); + }); + + test('should Update existing timeline savedObject with timelineId', async () => { + expect(mockPersistTimeline.mock.calls[0][1]).toEqual( + updateTimelineWithTimelineId.timelineId + ); + }); + + test('should Update existing timeline savedObject with timeline version', async () => { + expect(mockPersistTimeline.mock.calls[0][2]).toEqual(updateTimelineWithTimelineId.version); + }); + + test('should Update existing timeline savedObject witn given timeline', async () => { + expect(mockPersistTimeline.mock.calls[0][3]).toEqual(inputTimeline); + }); + + test('should NOT Update new pinned events', async () => { + expect(mockPersistPinnedEventOnTimeline).not.toBeCalled(); + }); + + test('should NOT Update notes', async () => { + expect(mockPersistNote).not.toBeCalled(); + }); + + test('returns 200 when create timeline successfully', async () => { + const response = await server.inject( + getUpdateTimelinesRequest(updateTimelineWithTimelineId), + context + ); + expect(response.status).toEqual(200); + }); + }); + + describe("Update a timeline that doesn't exist", () => { + beforeEach(() => { + jest.doMock('../saved_object', () => { + return { + getTimeline: mockGetTimeline.mockReturnValue(null), + getTimelineByTemplateTimelineId: mockGetTemplateTimeline.mockReturnValue(null), + persistTimeline: mockPersistTimeline, + }; + }); + + jest.doMock('../../pinned_event/saved_object', () => { + return { + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, + }; + }); + + jest.doMock('../../note/saved_object', () => { + return { + persistNote: mockPersistNote, + }; + }); + + const updateTimelinesRoute = jest.requireActual('./update_timelines_route') + .updateTimelinesRoute; + updateTimelinesRoute(server.router, createMockConfig(), securitySetup); + }); + + test('returns error message', async () => { + const response = await server.inject( + getUpdateTimelinesRequest(updateTimelineWithTimelineId), + context + ); + expect(response.body).toEqual({ + message: UPDATE_TIMELINE_ERROR_MESSAGE, + status_code: 405, + }); + }); + }); + }); + + describe('Manipulate template timeline', () => { + describe('Update an existing template timeline', () => { + beforeEach(async () => { + jest.doMock('../saved_object', () => { + return { + getTimeline: mockGetTimeline.mockReturnValue(mockGetTemplateTimelineValue), + getTimelineByTemplateTimelineId: mockGetTemplateTimeline.mockReturnValue({ + timeline: [mockGetTemplateTimelineValue], + }), + persistTimeline: mockPersistTimeline.mockReturnValue({ + timeline: updateTimelineWithTimelineId.timeline, + }), + }; + }); + + jest.doMock('../../pinned_event/saved_object', () => { + return { + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, + }; + }); + + jest.doMock('../../note/saved_object', () => { + return { + persistNote: mockPersistNote, + }; + }); + + const updateTimelinesRoute = jest.requireActual('./update_timelines_route') + .updateTimelinesRoute; + updateTimelinesRoute(server.router, createMockConfig(), securitySetup); + + const mockRequest = getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId); + await server.inject(mockRequest, context); + }); + + test('should Check if given timeline id exist', async () => { + expect(mockGetTimeline.mock.calls[0][1]).toEqual( + updateTemplateTimelineWithTimelineId.timelineId + ); + }); + + test('should Update existing template timeline with template timelineId', async () => { + expect(mockGetTemplateTimeline.mock.calls[0][1]).toEqual( + updateTemplateTimelineWithTimelineId.timelineId + ); + }); + + test('should Update existing template timeline with timeline version', async () => { + expect(mockPersistTimeline.mock.calls[0][2]).toEqual( + updateTemplateTimelineWithTimelineId.version + ); + }); + + test('should Update existing template timeline witn given timeline', async () => { + expect(mockPersistTimeline.mock.calls[0][3]).toEqual( + updateTemplateTimelineWithTimelineId.timeline + ); + }); + + test('should NOT Update new pinned events', async () => { + expect(mockPersistPinnedEventOnTimeline).not.toBeCalled(); + }); + + test('should NOT Update notes', async () => { + expect(mockPersistNote).not.toBeCalled(); + }); + + test('returns 200 when create template timeline successfully', async () => { + const response = await server.inject( + getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId), + context + ); + expect(response.status).toEqual(200); + }); + }); + + describe("Update a template timeline that doesn't exist", () => { + beforeEach(() => { + jest.doMock('../saved_object', () => { + return { + getTimeline: mockGetTimeline.mockReturnValue(null), + getTimelineByTemplateTimelineId: mockGetTemplateTimeline.mockReturnValue({ + timeline: [], + }), + persistTimeline: mockPersistTimeline, + }; + }); + + jest.doMock('../../pinned_event/saved_object', () => { + return { + persistPinnedEventOnTimeline: mockPersistPinnedEventOnTimeline, + }; + }); + + jest.doMock('../../note/saved_object', () => { + return { + persistNote: mockPersistNote, + }; + }); + + const updateTimelinesRoute = jest.requireActual('./update_timelines_route') + .updateTimelinesRoute; + updateTimelinesRoute(server.router, createMockConfig(), securitySetup); + }); + + test('returns error message', async () => { + const response = await server.inject( + getUpdateTimelinesRequest(updateTemplateTimelineWithTimelineId), + context + ); + expect(response.body).toEqual({ + message: UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + status_code: 405, + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/update_timelines_route.ts b/x-pack/plugins/siem/server/lib/timeline/routes/update_timelines_route.ts new file mode 100644 index 00000000000000..a0f3d11a1533de --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/update_timelines_route.ts @@ -0,0 +1,87 @@ +/* + * 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 { IRouter } from '../../../../../../../src/core/server'; + +import { TIMELINE_URL } from '../../../../common/constants'; +import { TimelineType } from '../../../../common/types/timeline'; + +import { SetupPlugins } from '../../../plugin'; +import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; +import { ConfigType } from '../../..'; + +import { transformError, buildSiemResponse } from '../../detection_engine/routes/utils'; +import { FrameworkRequest } from '../../framework'; + +import { updateTimelineSchema } from './schemas/update_timelines_schema'; +import { buildFrameworkRequest } from './utils/common'; +import { createTimelines, getTimeline, getTemplateTimeline } from './utils/create_timelines'; +import { checkIsFailureCases } from './utils/update_timelines'; + +export const updateTimelinesRoute = ( + router: IRouter, + config: ConfigType, + security: SetupPlugins['security'] +) => { + router.patch( + { + path: TIMELINE_URL, + validate: { + body: buildRouteValidation(updateTimelineSchema), + }, + options: { + tags: ['access:siem'], + }, + }, + // eslint-disable-next-line complexity + async (context, request, response) => { + const siemResponse = buildSiemResponse(response); + + try { + const frameworkRequest = await buildFrameworkRequest(context, security, request); + const { timelineId, timeline, version } = request.body; + const { templateTimelineId, templateTimelineVersion, timelineType } = timeline; + const isHandlingTemplateTimeline = timelineType === TimelineType.template; + const existTimeline = + timelineId != null ? await getTimeline(frameworkRequest, timelineId) : null; + + const existTemplateTimeline = + templateTimelineId != null + ? await getTemplateTimeline(frameworkRequest, templateTimelineId) + : null; + const errorObj = checkIsFailureCases( + isHandlingTemplateTimeline, + version, + templateTimelineVersion ?? null, + existTimeline, + existTemplateTimeline + ); + if (errorObj != null) { + return siemResponse.error(errorObj); + } + const updatedTimeline = await createTimelines( + (frameworkRequest as unknown) as FrameworkRequest, + timeline, + timelineId, + version + ); + return response.ok({ + body: { + data: { + persistTimeline: updatedTimeline, + }, + }, + }); + } catch (err) { + const error = transformError(err); + return siemResponse.error({ + body: error.message, + statusCode: error.statusCode, + }); + } + } + ); +}; diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/utils/common.ts b/x-pack/plugins/siem/server/lib/timeline/routes/utils/common.ts new file mode 100644 index 00000000000000..1036a74b74a03c --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/utils/common.ts @@ -0,0 +1,30 @@ +/* + * 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 { set } from 'lodash/fp'; + +import { SetupPlugins } from '../../../../plugin'; +import { KibanaRequest } from '../../../../../../../../src/core/server'; +import { RequestHandlerContext } from '../../../../../../../../target/types/core/server'; +import { FrameworkRequest } from '../../../framework'; + +export const buildFrameworkRequest = async ( + context: RequestHandlerContext, + security: SetupPlugins['security'], + request: KibanaRequest +): Promise => { + const savedObjectsClient = context.core.savedObjects.client; + const user = await security?.authc.getCurrentUser(request); + + return set( + 'user', + user, + set( + 'context.core.savedObjects.client', + savedObjectsClient, + request + ) + ); +}; diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/utils/create_timelines.ts b/x-pack/plugins/siem/server/lib/timeline/routes/utils/create_timelines.ts new file mode 100644 index 00000000000000..2c67a514cdf979 --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/utils/create_timelines.ts @@ -0,0 +1,150 @@ +/* + * 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 { isEmpty } from 'lodash/fp'; + +import * as timelineLib from '../../saved_object'; +import * as pinnedEventLib from '../../../pinned_event/saved_object'; +import * as noteLib from '../../../note/saved_object'; +import { FrameworkRequest } from '../../../framework'; +import { SavedTimeline, TimelineSavedObject } from '../../../../../common/types/timeline'; +import { SavedNote } from '../../../../../common/types/timeline/note'; +import { NoteResult, ResponseTimeline } from '../../../../graphql/types'; +export const CREATE_TIMELINE_ERROR_MESSAGE = + 'UPDATE timeline with POST is not allowed, please use PATCH instead'; +export const CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE = + 'UPDATE template timeline with POST is not allowed, please use PATCH instead'; + +export const saveTimelines = ( + frameworkRequest: FrameworkRequest, + timeline: SavedTimeline, + timelineSavedObjectId?: string | null, + timelineVersion?: string | null +): Promise => { + return timelineLib.persistTimeline( + frameworkRequest, + timelineSavedObjectId ?? null, + timelineVersion ?? null, + timeline + ); +}; + +export const savePinnedEvents = ( + frameworkRequest: FrameworkRequest, + timelineSavedObjectId: string, + pinnedEventIds: string[] +) => + Promise.all( + pinnedEventIds.map(eventId => + pinnedEventLib.persistPinnedEventOnTimeline( + frameworkRequest, + null, // pinnedEventSavedObjectId + eventId, + timelineSavedObjectId + ) + ) + ); + +export const saveNotes = ( + frameworkRequest: FrameworkRequest, + timelineSavedObjectId: string, + timelineVersion?: string | null, + existingNoteIds?: string[], + newNotes?: NoteResult[] +) => { + return Promise.all( + newNotes?.map(note => { + const newNote: SavedNote = { + eventId: note.eventId, + note: note.note, + timelineId: timelineSavedObjectId, + }; + + return noteLib.persistNote( + frameworkRequest, + existingNoteIds?.find(nId => nId === note.noteId) ?? null, + timelineVersion ?? null, + newNote + ); + }) ?? [] + ); +}; + +export const createTimelines = async ( + frameworkRequest: FrameworkRequest, + timeline: SavedTimeline, + timelineSavedObjectId?: string | null, + timelineVersion?: string | null, + pinnedEventIds?: string[] | null, + notes?: NoteResult[], + existingNoteIds?: string[] +): Promise => { + const responseTimeline = await saveTimelines( + frameworkRequest, + timeline, + timelineSavedObjectId, + timelineVersion + ); + const newTimelineSavedObjectId = responseTimeline.timeline.savedObjectId; + const newTimelineVersion = responseTimeline.timeline.version; + + let myPromises: unknown[] = []; + if (pinnedEventIds != null && !isEmpty(pinnedEventIds)) { + myPromises = [ + ...myPromises, + savePinnedEvents( + frameworkRequest, + timelineSavedObjectId ?? newTimelineSavedObjectId, + pinnedEventIds + ), + ]; + } + if (!isEmpty(notes)) { + myPromises = [ + ...myPromises, + saveNotes( + frameworkRequest, + timelineSavedObjectId ?? newTimelineSavedObjectId, + newTimelineVersion, + existingNoteIds, + notes + ), + ]; + } + + if (myPromises.length > 0) { + await Promise.all(myPromises); + } + + return responseTimeline; +}; + +export const getTimeline = async ( + frameworkRequest: FrameworkRequest, + savedObjectId: string +): Promise => { + let timeline = null; + try { + timeline = await timelineLib.getTimeline(frameworkRequest, savedObjectId); + // eslint-disable-next-line no-empty + } catch (e) {} + return timeline; +}; + +export const getTemplateTimeline = async ( + frameworkRequest: FrameworkRequest, + templateTimelineId: string +): Promise => { + let templateTimeline = null; + try { + templateTimeline = await timelineLib.getTimelineByTemplateTimelineId( + frameworkRequest, + templateTimelineId + ); + } catch (e) { + return null; + } + return templateTimeline.timeline[0]; +}; diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/utils/export_timelines.ts b/x-pack/plugins/siem/server/lib/timeline/routes/utils/export_timelines.ts index 677891fa16c024..ea9a5fab66805c 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/utils/export_timelines.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/utils/export_timelines.ts @@ -4,13 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { NoteSavedObject } from '../../../note/types'; -import { PinnedEventSavedObject } from '../../../pinned_event/types'; -import { convertSavedObjectToSavedTimeline } from '../../convert_saved_object_to_savedtimeline'; - -import { convertSavedObjectToSavedPinnedEvent } from '../../../pinned_event/saved_object'; -import { convertSavedObjectToSavedNote } from '../../../note/saved_object'; - import { SavedObjectsClient, SavedObjectsFindOptions, @@ -22,11 +15,20 @@ import { ExportTimelineSavedObjectsClient, ExportedNotes, TimelineSavedObject, -} from '../../types'; + ExportTimelineNotFoundError, +} from '../../../../../common/types/timeline'; +import { NoteSavedObject } from '../../../../../common/types/timeline/note'; +import { PinnedEventSavedObject } from '../../../../../common/types/timeline/pinned_event'; + import { transformDataToNdjson } from '../../../../utils/read_stream/create_stream_from_ndjson'; + +import { convertSavedObjectToSavedPinnedEvent } from '../../../pinned_event/saved_object'; +import { convertSavedObjectToSavedNote } from '../../../note/saved_object'; import { pinnedEventSavedObjectType } from '../../../pinned_event/saved_object_mappings'; import { noteSavedObjectType } from '../../../note/saved_object_mappings'; + import { timelineSavedObjectType } from '../../saved_object_mappings'; +import { convertSavedObjectToSavedTimeline } from '../../convert_saved_object_to_savedtimeline'; export type TimelineSavedObjectsClient = Pick< SavedObjectsClient, @@ -126,12 +128,23 @@ const getTimelines = async ( ) ); - const timelineObjects: TimelineSavedObject[] | undefined = - savedObjects != null - ? savedObjects.saved_objects.map((savedObject: unknown) => { - return convertSavedObjectToSavedTimeline(savedObject); - }) - : []; + const timelineObjects: { + timelines: TimelineSavedObject[]; + errors: ExportTimelineNotFoundError[]; + } = savedObjects.saved_objects.reduce( + (acc, savedObject) => { + return savedObject.error == null + ? { + errors: acc.errors, + timelines: [...acc.timelines, convertSavedObjectToSavedTimeline(savedObject)], + } + : { errors: [...acc.errors, savedObject.error], timelines: acc.timelines }; + }, + { + timelines: [] as TimelineSavedObject[], + errors: [] as ExportTimelineNotFoundError[], + } + ); return timelineObjects; }; @@ -139,12 +152,8 @@ const getTimelines = async ( const getTimelinesFromObjects = async ( savedObjectsClient: ExportTimelineSavedObjectsClient, ids: string[] -): Promise => { - const timelines: TimelineSavedObject[] = await getTimelines(savedObjectsClient, ids); - // To Do for feature freeze - // if (timelines.length !== request.body.ids.length) { - // //figure out which is missing to tell user - // } +): Promise> => { + const { timelines, errors } = await getTimelines(savedObjectsClient, ids); const [notes, pinnedEventIds] = await Promise.all([ Promise.all(ids.map(timelineId => getNotesByTimelineId(savedObjectsClient, timelineId))), @@ -178,7 +187,7 @@ const getTimelinesFromObjects = async ( return acc; }, []); - return myResponse ?? []; + return [...myResponse, ...errors] ?? []; }; export const getExportTimelineByObjectIds = async ({ diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/utils/import_timelines.ts b/x-pack/plugins/siem/server/lib/timeline/routes/utils/import_timelines.ts index f69a715f9b2c99..9e120cdc023dc1 100644 --- a/x-pack/plugins/siem/server/lib/timeline/routes/utils/import_timelines.ts +++ b/x-pack/plugins/siem/server/lib/timeline/routes/utils/import_timelines.ts @@ -7,20 +7,10 @@ import uuid from 'uuid'; import { has } from 'lodash/fp'; import { createBulkErrorObject, BulkError } from '../../../detection_engine/routes/utils'; -import { PinnedEvent } from '../../../pinned_event/saved_object'; -import { Note } from '../../../note/saved_object'; - -import { Timeline } from '../../saved_object'; -import { SavedTimeline } from '../../types'; -import { FrameworkRequest } from '../../../framework'; -import { SavedNote } from '../../../note/types'; +import { SavedTimeline } from '../../../../../common/types/timeline'; import { NoteResult } from '../../../../graphql/types'; import { HapiReadableStream } from '../../../detection_engine/rules/types'; -const pinnedEventLib = new PinnedEvent(); -const timelineLib = new Timeline(); -const noteLib = new Note(); - export interface ImportTimelinesSchema { success: boolean; success_count: number; @@ -84,100 +74,6 @@ export const getTupleDuplicateErrorsAndUniqueTimeline = ( return [Array.from(errors.values()), Array.from(timelinesAcc.values())]; }; -export const saveTimelines = async ( - frameworkRequest: FrameworkRequest, - timeline: SavedTimeline, - timelineSavedObjectId?: string | null, - timelineVersion?: string | null -) => { - const newTimelineRes = await timelineLib.persistTimeline( - frameworkRequest, - timelineSavedObjectId ?? null, - timelineVersion ?? null, - timeline - ); - - return { - newTimelineSavedObjectId: newTimelineRes?.timeline?.savedObjectId ?? null, - newTimelineVersion: newTimelineRes?.timeline?.version ?? null, - }; -}; - -export const savePinnedEvents = ( - frameworkRequest: FrameworkRequest, - timelineSavedObjectId: string, - pinnedEventIds?: string[] | null -) => { - return ( - pinnedEventIds?.map(eventId => { - return pinnedEventLib.persistPinnedEventOnTimeline( - frameworkRequest, - null, // pinnedEventSavedObjectId - eventId, - timelineSavedObjectId - ); - }) ?? [] - ); -}; - -export const saveNotes = ( - frameworkRequest: FrameworkRequest, - timelineSavedObjectId: string, - timelineVersion?: string | null, - existingNoteIds?: string[], - newNotes?: NoteResult[] -) => { - return Promise.all( - newNotes?.map(note => { - const newNote: SavedNote = { - eventId: note.eventId, - note: note.note, - timelineId: timelineSavedObjectId, - }; - - return noteLib.persistNote( - frameworkRequest, - existingNoteIds?.find(nId => nId === note.noteId) ?? null, - timelineVersion ?? null, - newNote - ); - }) ?? [] - ); -}; - -export const createTimelines = async ( - frameworkRequest: FrameworkRequest, - timeline: SavedTimeline, - timelineSavedObjectId?: string | null, - timelineVersion?: string | null, - pinnedEventIds?: string[] | null, - notes?: NoteResult[], - existingNoteIds?: string[] -) => { - const { newTimelineSavedObjectId, newTimelineVersion } = await saveTimelines( - frameworkRequest, - timeline, - timelineSavedObjectId, - timelineVersion - ); - await Promise.all([ - savePinnedEvents( - frameworkRequest, - timelineSavedObjectId ?? newTimelineSavedObjectId, - pinnedEventIds - ), - saveNotes( - frameworkRequest, - timelineSavedObjectId ?? newTimelineSavedObjectId, - newTimelineVersion, - existingNoteIds, - notes - ), - ]); - - return newTimelineSavedObjectId; -}; - export const isImportRegular = ( importTimelineResponse: ImportTimelineResponse ): importTimelineResponse is ImportRegular => { @@ -189,3 +85,15 @@ export const isBulkError = ( ): importRuleResponse is BulkError => { return has('error', importRuleResponse); }; + +export const timelineSavedObjectOmittedFields = [ + 'globalNotes', + 'eventNotes', + 'pinnedEventIds', + 'version', + 'savedObjectId', + 'created', + 'createdBy', + 'updated', + 'updatedBy', +]; diff --git a/x-pack/plugins/siem/server/lib/timeline/routes/utils/update_timelines.ts b/x-pack/plugins/siem/server/lib/timeline/routes/utils/update_timelines.ts new file mode 100644 index 00000000000000..6a25d8def91160 --- /dev/null +++ b/x-pack/plugins/siem/server/lib/timeline/routes/utils/update_timelines.ts @@ -0,0 +1,81 @@ +/* + * 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 { TimelineSavedObject } from '../../../../../common/types/timeline'; + +export const UPDATE_TIMELINE_ERROR_MESSAGE = + 'CREATE timeline with PATCH is not allowed, please use POST instead'; +export const UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE = + 'CREATE template timeline with PATCH is not allowed, please use POST instead'; +export const NO_MATCH_VERSION_ERROR_MESSAGE = + 'TimelineVersion conflict: The given version doesn not match with existing timeline'; +export const NO_MATCH_ID_ERROR_MESSAGE = + "Timeline id doesn't match with existing template timeline"; +export const OLDER_VERSION_ERROR_MESSAGE = + 'Template timelineVersion conflict: The given version is older then existing version'; + +export const checkIsFailureCases = ( + isHandlingTemplateTimeline: boolean, + version: string | null, + templateTimelineVersion: number | null, + existTimeline: TimelineSavedObject | null, + existTemplateTimeline: TimelineSavedObject | null +) => { + if (!isHandlingTemplateTimeline && existTimeline == null) { + return { + body: UPDATE_TIMELINE_ERROR_MESSAGE, + statusCode: 405, + }; + } else if (isHandlingTemplateTimeline && existTemplateTimeline == null) { + // Throw error to create template timeline in patch + return { + body: UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + statusCode: 405, + }; + } else if ( + isHandlingTemplateTimeline && + existTimeline != null && + existTemplateTimeline != null && + existTimeline.savedObjectId !== existTemplateTimeline.savedObjectId + ) { + // Throw error you can not have a no matching between your timeline and your template timeline during an update + return { + body: NO_MATCH_ID_ERROR_MESSAGE, + statusCode: 409, + }; + } else if (!isHandlingTemplateTimeline && existTimeline?.version !== version) { + // throw error 409 conflict timeline + return { + body: NO_MATCH_VERSION_ERROR_MESSAGE, + statusCode: 409, + }; + } else if ( + isHandlingTemplateTimeline && + existTemplateTimeline != null && + existTemplateTimeline.templateTimelineVersion == null && + existTemplateTimeline.version !== version + ) { + // throw error 409 conflict timeline + return { + body: NO_MATCH_VERSION_ERROR_MESSAGE, + statusCode: 409, + }; + } else if ( + isHandlingTemplateTimeline && + templateTimelineVersion != null && + existTemplateTimeline != null && + existTemplateTimeline.templateTimelineVersion != null && + existTemplateTimeline.templateTimelineVersion >= templateTimelineVersion + ) { + // Throw error you can not update a template timeline version with an old version + return { + body: OLDER_VERSION_ERROR_MESSAGE, + statusCode: 409, + }; + } else { + return null; + } +}; diff --git a/x-pack/plugins/siem/server/lib/timeline/saved_object.ts b/x-pack/plugins/siem/server/lib/timeline/saved_object.ts index e8cd27947589fc..d2df7589f3c4a9 100644 --- a/x-pack/plugins/siem/server/lib/timeline/saved_object.ts +++ b/x-pack/plugins/siem/server/lib/timeline/saved_object.ts @@ -8,260 +8,308 @@ import { getOr } from 'lodash/fp'; import { SavedObjectsFindOptions } from '../../../../../../src/core/server'; import { UNAUTHENTICATED_USER } from '../../../common/constants'; +import { NoteSavedObject } from '../../../common/types/timeline/note'; +import { PinnedEventSavedObject } from '../../../common/types/timeline/pinned_event'; +import { SavedTimeline, TimelineSavedObject, TimelineType } from '../../../common/types/timeline'; import { ResponseTimeline, PageInfoTimeline, SortTimeline, ResponseFavoriteTimeline, TimelineResult, + Maybe, } from '../../graphql/types'; import { FrameworkRequest } from '../framework'; -import { Note } from '../note/saved_object'; -import { NoteSavedObject } from '../note/types'; -import { PinnedEventSavedObject } from '../pinned_event/types'; -import { PinnedEvent } from '../pinned_event/saved_object'; +import * as note from '../note/saved_object'; +import * as pinnedEvent from '../pinned_event/saved_object'; import { convertSavedObjectToSavedTimeline } from './convert_saved_object_to_savedtimeline'; import { pickSavedTimeline } from './pick_saved_timeline'; import { timelineSavedObjectType } from './saved_object_mappings'; -import { SavedTimeline, TimelineSavedObject } from './types'; interface ResponseTimelines { timeline: TimelineSavedObject[]; totalCount: number; } -export class Timeline { - private readonly note = new Note(); - private readonly pinnedEvent = new PinnedEvent(); +export interface ResponseTemplateTimeline { + code?: Maybe; - public async getTimeline( - request: FrameworkRequest, - timelineId: string - ): Promise { - return this.getSavedTimeline(request, timelineId); - } + message?: Maybe; + + templateTimeline: TimelineResult; +} - public async getAllTimeline( +export interface Timeline { + getTimeline: (request: FrameworkRequest, timelineId: string) => Promise; + + getAllTimeline: ( request: FrameworkRequest, onlyUserFavorite: boolean | null, pageInfo: PageInfoTimeline | null, search: string | null, sort: SortTimeline | null - ): Promise { - const options: SavedObjectsFindOptions = { - type: timelineSavedObjectType, - perPage: pageInfo != null ? pageInfo.pageSize : undefined, - page: pageInfo != null ? pageInfo.pageIndex : undefined, - search: search != null ? search : undefined, - searchFields: onlyUserFavorite - ? ['title', 'description', 'favorite.keySearch'] - : ['title', 'description'], - sortField: sort != null ? sort.sortField : undefined, - sortOrder: sort != null ? sort.sortOrder : undefined, - }; - - return this.getAllSavedTimeline(request, options); - } + ) => Promise; - public async persistFavorite( + persistFavorite: ( request: FrameworkRequest, timelineId: string | null - ): Promise { - const userName = request.user?.username ?? UNAUTHENTICATED_USER; - const fullName = request.user?.full_name ?? ''; - try { - let timeline: SavedTimeline = {}; - if (timelineId != null) { - const { - eventIdToNoteIds, - notes, - noteIds, - pinnedEventIds, - pinnedEventsSaveObject, - savedObjectId, - version, - ...savedTimeline - } = await this.getBasicSavedTimeline(request, timelineId); - timelineId = savedObjectId; // eslint-disable-line no-param-reassign - timeline = savedTimeline; - } + ) => Promise; - const userFavoriteTimeline = { - keySearch: userName != null ? convertStringToBase64(userName) : null, - favoriteDate: new Date().valueOf(), - fullName, - userName, - }; - if (timeline.favorite != null) { - const alreadyExistsTimelineFavoriteByUser = timeline.favorite.findIndex( - user => user.userName === userName - ); - - timeline.favorite = - alreadyExistsTimelineFavoriteByUser > -1 - ? [ - ...timeline.favorite.slice(0, alreadyExistsTimelineFavoriteByUser), - ...timeline.favorite.slice(alreadyExistsTimelineFavoriteByUser + 1), - ] - : [...timeline.favorite, userFavoriteTimeline]; - } else if (timeline.favorite == null) { - timeline.favorite = [userFavoriteTimeline]; - } + persistTimeline: ( + request: FrameworkRequest, + timelineId: string | null, + version: string | null, + timeline: SavedTimeline, + timelineType?: TimelineType | null + ) => Promise; - const persistResponse = await this.persistTimeline(request, timelineId, null, timeline); + deleteTimeline: (request: FrameworkRequest, timelineIds: string[]) => Promise; + convertStringToBase64: (text: string) => string; + timelineWithReduxProperties: ( + notes: NoteSavedObject[], + pinnedEvents: PinnedEventSavedObject[], + timeline: TimelineSavedObject, + userName: string + ) => TimelineSavedObject; +} + +export const getTimeline = async ( + request: FrameworkRequest, + timelineId: string +): Promise => { + return getSavedTimeline(request, timelineId); +}; + +export const getTimelineByTemplateTimelineId = async ( + request: FrameworkRequest, + templateTimelineId: string +): Promise<{ + totalCount: number; + timeline: TimelineSavedObject[]; +}> => { + const options: SavedObjectsFindOptions = { + type: timelineSavedObjectType, + filter: `siem-ui-timeline.attributes.templateTimelineId: ${templateTimelineId}`, + }; + return getAllSavedTimeline(request, options); +}; + +export const getAllTimeline = async ( + request: FrameworkRequest, + onlyUserFavorite: boolean | null, + pageInfo: PageInfoTimeline | null, + search: string | null, + sort: SortTimeline | null +): Promise => { + const options: SavedObjectsFindOptions = { + type: timelineSavedObjectType, + perPage: pageInfo != null ? pageInfo.pageSize : undefined, + page: pageInfo != null ? pageInfo.pageIndex : undefined, + search: search != null ? search : undefined, + searchFields: onlyUserFavorite + ? ['title', 'description', 'favorite.keySearch'] + : ['title', 'description'], + sortField: sort != null ? sort.sortField : undefined, + sortOrder: sort != null ? sort.sortOrder : undefined, + }; + return getAllSavedTimeline(request, options); +}; + +export const persistFavorite = async ( + request: FrameworkRequest, + timelineId: string | null +): Promise => { + const userName = request.user?.username ?? UNAUTHENTICATED_USER; + const fullName = request.user?.full_name ?? ''; + try { + let timeline: SavedTimeline = {}; + if (timelineId != null) { + const { + eventIdToNoteIds, + notes, + noteIds, + pinnedEventIds, + pinnedEventsSaveObject, + savedObjectId, + version, + ...savedTimeline + } = await getBasicSavedTimeline(request, timelineId); + timelineId = savedObjectId; // eslint-disable-line no-param-reassign + timeline = savedTimeline; + } + + const userFavoriteTimeline = { + keySearch: userName != null ? convertStringToBase64(userName) : null, + favoriteDate: new Date().valueOf(), + fullName, + userName, + }; + if (timeline.favorite != null) { + const alreadyExistsTimelineFavoriteByUser = timeline.favorite.findIndex( + user => user.userName === userName + ); + + timeline.favorite = + alreadyExistsTimelineFavoriteByUser > -1 + ? [ + ...timeline.favorite.slice(0, alreadyExistsTimelineFavoriteByUser), + ...timeline.favorite.slice(alreadyExistsTimelineFavoriteByUser + 1), + ] + : [...timeline.favorite, userFavoriteTimeline]; + } else if (timeline.favorite == null) { + timeline.favorite = [userFavoriteTimeline]; + } + + const persistResponse = await persistTimeline(request, timelineId, null, timeline); + return { + savedObjectId: persistResponse.timeline.savedObjectId, + version: persistResponse.timeline.version, + favorite: + persistResponse.timeline.favorite != null + ? persistResponse.timeline.favorite.filter(fav => fav.userName === userName) + : [], + }; + } catch (err) { + if (getOr(null, 'output.statusCode', err) === 403) { return { - savedObjectId: persistResponse.timeline.savedObjectId, - version: persistResponse.timeline.version, - favorite: - persistResponse.timeline.favorite != null - ? persistResponse.timeline.favorite.filter(fav => fav.userName === userName) - : [], + savedObjectId: '', + version: '', + favorite: [], + code: 403, + message: err.message, }; - } catch (err) { - if (getOr(null, 'output.statusCode', err) === 403) { - return { - savedObjectId: '', - version: '', - favorite: [], - code: 403, - message: err.message, - }; - } - throw err; } + throw err; } +}; - public async persistTimeline( - request: FrameworkRequest, - timelineId: string | null, - version: string | null, - timeline: SavedTimeline - ): Promise { - const savedObjectsClient = request.context.core.savedObjects.client; - try { - if (timelineId == null) { - // Create new timeline - const newTimeline = convertSavedObjectToSavedTimeline( - await savedObjectsClient.create( - timelineSavedObjectType, - pickSavedTimeline(timelineId, timeline, request.user) - ) - ); - return { - code: 200, - message: 'success', - timeline: newTimeline, - }; - } - // Update Timeline - await savedObjectsClient.update( - timelineSavedObjectType, - timelineId, - pickSavedTimeline(timelineId, timeline, request.user), - { - version: version || undefined, - } +export const persistTimeline = async ( + request: FrameworkRequest, + timelineId: string | null, + version: string | null, + timeline: SavedTimeline +): Promise => { + const savedObjectsClient = request.context.core.savedObjects.client; + try { + if (timelineId == null) { + // Create new timeline + const newTimeline = convertSavedObjectToSavedTimeline( + await savedObjectsClient.create( + timelineSavedObjectType, + pickSavedTimeline(timelineId, timeline, request.user) + ) ); - return { code: 200, message: 'success', - timeline: await this.getSavedTimeline(request, timelineId), + timeline: newTimeline, }; - } catch (err) { - if (timelineId != null && savedObjectsClient.errors.isConflictError(err)) { - return { - code: 409, - message: err.message, - timeline: await this.getSavedTimeline(request, timelineId), - }; - } else if (getOr(null, 'output.statusCode', err) === 403) { - const timelineToReturn: TimelineResult = { - ...timeline, - savedObjectId: '', - version: '', - }; - return { - code: 403, - message: err.message, - timeline: timelineToReturn, - }; + } + // Update Timeline + await savedObjectsClient.update( + timelineSavedObjectType, + timelineId, + pickSavedTimeline(timelineId, timeline, request.user), + { + version: version || undefined, } - throw err; + ); + + return { + code: 200, + message: 'success', + timeline: await getSavedTimeline(request, timelineId), + }; + } catch (err) { + if (timelineId != null && savedObjectsClient.errors.isConflictError(err)) { + return { + code: 409, + message: err.message, + timeline: await getSavedTimeline(request, timelineId), + }; + } else if (getOr(null, 'output.statusCode', err) === 403) { + const timelineToReturn: TimelineResult = { + ...timeline, + savedObjectId: '', + version: '', + }; + return { + code: 403, + message: err.message, + timeline: timelineToReturn, + }; } + throw err; } +}; - public async deleteTimeline(request: FrameworkRequest, timelineIds: string[]) { - const savedObjectsClient = request.context.core.savedObjects.client; - - await Promise.all( - timelineIds.map(timelineId => - Promise.all([ - savedObjectsClient.delete(timelineSavedObjectType, timelineId), - this.note.deleteNoteByTimelineId(request, timelineId), - this.pinnedEvent.deleteAllPinnedEventsOnTimeline(request, timelineId), - ]) - ) - ); - } +export const deleteTimeline = async (request: FrameworkRequest, timelineIds: string[]) => { + const savedObjectsClient = request.context.core.savedObjects.client; - private async getBasicSavedTimeline(request: FrameworkRequest, timelineId: string) { - const savedObjectsClient = request.context.core.savedObjects.client; - const savedObject = await savedObjectsClient.get(timelineSavedObjectType, timelineId); + await Promise.all( + timelineIds.map(timelineId => + Promise.all([ + savedObjectsClient.delete(timelineSavedObjectType, timelineId), + note.deleteNoteByTimelineId(request, timelineId), + pinnedEvent.deleteAllPinnedEventsOnTimeline(request, timelineId), + ]) + ) + ); +}; - return convertSavedObjectToSavedTimeline(savedObject); - } +const getBasicSavedTimeline = async (request: FrameworkRequest, timelineId: string) => { + const savedObjectsClient = request.context.core.savedObjects.client; + const savedObject = await savedObjectsClient.get(timelineSavedObjectType, timelineId); + + return convertSavedObjectToSavedTimeline(savedObject); +}; - private async getSavedTimeline(request: FrameworkRequest, timelineId: string) { - const userName = request.user?.username ?? UNAUTHENTICATED_USER; +const getSavedTimeline = async (request: FrameworkRequest, timelineId: string) => { + const userName = request.user?.username ?? UNAUTHENTICATED_USER; - const savedObjectsClient = request.context.core.savedObjects.client; - const savedObject = await savedObjectsClient.get(timelineSavedObjectType, timelineId); - const timelineSaveObject = convertSavedObjectToSavedTimeline(savedObject); - const timelineWithNotesAndPinnedEvents = await Promise.all([ - this.note.getNotesByTimelineId(request, timelineSaveObject.savedObjectId), - this.pinnedEvent.getAllPinnedEventsByTimelineId(request, timelineSaveObject.savedObjectId), - Promise.resolve(timelineSaveObject), - ]); + const savedObjectsClient = request.context.core.savedObjects.client; + const savedObject = await savedObjectsClient.get(timelineSavedObjectType, timelineId); + const timelineSaveObject = convertSavedObjectToSavedTimeline(savedObject); + const timelineWithNotesAndPinnedEvents = await Promise.all([ + note.getNotesByTimelineId(request, timelineSaveObject.savedObjectId), + pinnedEvent.getAllPinnedEventsByTimelineId(request, timelineSaveObject.savedObjectId), + Promise.resolve(timelineSaveObject), + ]); - const [notes, pinnedEvents, timeline] = timelineWithNotesAndPinnedEvents; + const [notes, pinnedEvents, timeline] = timelineWithNotesAndPinnedEvents; - return timelineWithReduxProperties(notes, pinnedEvents, timeline, userName); + return timelineWithReduxProperties(notes, pinnedEvents, timeline, userName); +}; + +const getAllSavedTimeline = async (request: FrameworkRequest, options: SavedObjectsFindOptions) => { + const userName = request.user?.username ?? UNAUTHENTICATED_USER; + const savedObjectsClient = request.context.core.savedObjects.client; + if (options.searchFields != null && options.searchFields.includes('favorite.keySearch')) { + options.search = `${options.search != null ? options.search : ''} ${ + userName != null ? convertStringToBase64(userName) : null + }`; } - private async getAllSavedTimeline(request: FrameworkRequest, options: SavedObjectsFindOptions) { - const userName = request.user?.username ?? UNAUTHENTICATED_USER; - const savedObjectsClient = request.context.core.savedObjects.client; - if (options.searchFields != null && options.searchFields.includes('favorite.keySearch')) { - options.search = `${options.search != null ? options.search : ''} ${ - userName != null ? convertStringToBase64(userName) : null - }`; - } + const savedObjects = await savedObjectsClient.find(options); - const savedObjects = await savedObjectsClient.find(options); - - const timelinesWithNotesAndPinnedEvents = await Promise.all( - savedObjects.saved_objects.map(async savedObject => { - const timelineSaveObject = convertSavedObjectToSavedTimeline(savedObject); - return Promise.all([ - this.note.getNotesByTimelineId(request, timelineSaveObject.savedObjectId), - this.pinnedEvent.getAllPinnedEventsByTimelineId( - request, - timelineSaveObject.savedObjectId - ), - Promise.resolve(timelineSaveObject), - ]); - }) - ); + const timelinesWithNotesAndPinnedEvents = await Promise.all( + savedObjects.saved_objects.map(async savedObject => { + const timelineSaveObject = convertSavedObjectToSavedTimeline(savedObject); + return Promise.all([ + note.getNotesByTimelineId(request, timelineSaveObject.savedObjectId), + pinnedEvent.getAllPinnedEventsByTimelineId(request, timelineSaveObject.savedObjectId), + Promise.resolve(timelineSaveObject), + ]); + }) + ); - return { - totalCount: savedObjects.total, - timeline: timelinesWithNotesAndPinnedEvents.map(([notes, pinnedEvents, timeline]) => - timelineWithReduxProperties(notes, pinnedEvents, timeline, userName) - ), - }; - } -} + return { + totalCount: savedObjects.total, + timeline: timelinesWithNotesAndPinnedEvents.map(([notes, pinnedEvents, timeline]) => + timelineWithReduxProperties(notes, pinnedEvents, timeline, userName) + ), + }; +}; export const convertStringToBase64 = (text: string): string => Buffer.from(text).toString('base64'); @@ -283,11 +331,9 @@ export const timelineWithReduxProperties = ( timeline.favorite != null && userName != null ? timeline.favorite.filter(fav => fav.userName === userName) : [], - eventIdToNoteIds: notes.filter(note => note.eventId != null), - noteIds: notes - .filter(note => note.eventId == null && note.noteId != null) - .map(note => note.noteId), + eventIdToNoteIds: notes.filter(n => n.eventId != null), + noteIds: notes.filter(n => n.eventId == null && n.noteId != null).map(n => n.noteId), notes, - pinnedEventIds: pinnedEvents.map(pinnedEvent => pinnedEvent.eventId), + pinnedEventIds: pinnedEvents.map(e => e.eventId), pinnedEventsSaveObject: pinnedEvents, }); diff --git a/x-pack/plugins/siem/server/lib/timeline/saved_object_mappings.ts b/x-pack/plugins/siem/server/lib/timeline/saved_object_mappings.ts index b956e0f98fcb62..1cab24d0879ff6 100644 --- a/x-pack/plugins/siem/server/lib/timeline/saved_object_mappings.ts +++ b/x-pack/plugins/siem/server/lib/timeline/saved_object_mappings.ts @@ -231,6 +231,15 @@ export const timelineSavedObjectMappings = { title: { type: 'text', }, + templateTimelineId: { + type: 'text', + }, + templateTimelineVersion: { + type: 'integer', + }, + timelineType: { + type: 'keyword', + }, dateRange: { properties: { start: { diff --git a/x-pack/plugins/siem/server/routes/index.ts b/x-pack/plugins/siem/server/routes/index.ts index 1c03823e85fd7a..ffad86a09cee72 100644 --- a/x-pack/plugins/siem/server/routes/index.ts +++ b/x-pack/plugins/siem/server/routes/index.ts @@ -30,6 +30,8 @@ import { findRulesStatusesRoute } from '../lib/detection_engine/routes/rules/fin import { getPrepackagedRulesStatusRoute } from '../lib/detection_engine/routes/rules/get_prepackaged_rules_status_route'; import { importTimelinesRoute } from '../lib/timeline/routes/import_timelines_route'; import { exportTimelinesRoute } from '../lib/timeline/routes/export_timelines_route'; +import { createTimelinesRoute } from '../lib/timeline/routes/create_timelines_route'; +import { updateTimelinesRoute } from '../lib/timeline/routes/update_timelines_route'; import { SetupPlugins } from '../plugin'; import { ConfigType } from '../config'; @@ -55,6 +57,8 @@ export const initRoutes = ( patchRulesBulkRoute(router); deleteRulesBulkRoute(router); + createTimelinesRoute(router, config, security); + updateTimelinesRoute(router, config, security); importRulesRoute(router, config); exportRulesRoute(router, config); diff --git a/x-pack/plugins/siem/server/utils/typed_resolvers.ts b/x-pack/plugins/siem/server/utils/typed_resolvers.ts index da38e8a1e1bf28..4f19bd54b01f0c 100644 --- a/x-pack/plugins/siem/server/utils/typed_resolvers.ts +++ b/x-pack/plugins/siem/server/utils/typed_resolvers.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as runtimeTypes from 'io-ts'; import { GraphQLResolveInfo } from 'graphql'; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -106,6 +105,3 @@ export type ChildResolverOf = ResolverWithParent< Resolver_, ResultOf >; - -export const unionWithNullType = (type: T) => - runtimeTypes.union([type, runtimeTypes.null]); From fc79c06fc0690945b0c31f726d093153f9ddcb7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Wed, 29 Apr 2020 10:40:45 +0100 Subject: [PATCH 03/26] [Telemetry] Fix inconsistent search behaviour in Advanced Settings (#64510) --- ...telemetry_management_section.test.tsx.snap | 492 ++++++++++++++++++ .../telemetry_management_section.test.tsx | 284 ++++++++++ .../telemetry_management_section.tsx | 4 +- 3 files changed, 779 insertions(+), 1 deletion(-) create mode 100644 src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap create mode 100644 src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx diff --git a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap new file mode 100644 index 00000000000000..8c0117e5a72664 --- /dev/null +++ b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap @@ -0,0 +1,492 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TelemetryManagementSectionComponent renders as expected 1`] = ` + + + + + + +

+ +

+
+
+
+ + + + , + } + } + /> +

+ } + /> + + +

+ + + , + } + } + /> +

+

+ + + +

+ , + "displayName": "Provide usage statistics", + "name": "telemetry:enabled", + "type": "boolean", + "value": true, + } + } + toasts={null} + /> +
+
+
+`; + +exports[`TelemetryManagementSectionComponent renders null because allowChangingOptInStatus is false 1`] = ` + +`; + +exports[`TelemetryManagementSectionComponent renders null because query does not match the SEARCH_TERMS 1`] = ` + +`; + +exports[`TelemetryManagementSectionComponent test the wrapper (for coverage purposes) 1`] = `""`; diff --git a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx new file mode 100644 index 00000000000000..d0c2bd13f802d7 --- /dev/null +++ b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx @@ -0,0 +1,284 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; +import { TelemetryManagementSection } from './telemetry_management_section'; +import { TelemetryService } from '../../../telemetry/public/services'; +import { coreMock } from '../../../../core/public/mocks'; +import { telemetryManagementSectionWrapper } from './telemetry_management_section_wrapper'; + +describe('TelemetryManagementSectionComponent', () => { + const coreStart = coreMock.createStart(); + const coreSetup = coreMock.createSetup(); + + it('renders as expected', () => { + const onQueryMatchChange = jest.fn(); + const telemetryService = new TelemetryService({ + config: { + enabled: true, + url: '', + banner: true, + allowChangingOptInStatus: true, + optIn: true, + optInStatusUrl: '', + sendUsageFrom: 'browser', + }, + reportOptInStatusChange: false, + notifications: coreStart.notifications, + http: coreSetup.http, + }); + + expect( + shallowWithIntl( + + ) + ).toMatchSnapshot(); + }); + + it('renders null because query does not match the SEARCH_TERMS', () => { + const onQueryMatchChange = jest.fn(); + const telemetryService = new TelemetryService({ + config: { + enabled: true, + url: '', + banner: true, + allowChangingOptInStatus: true, + optIn: false, + optInStatusUrl: '', + sendUsageFrom: 'browser', + }, + reportOptInStatusChange: false, + notifications: coreStart.notifications, + http: coreSetup.http, + }); + + const component = mountWithIntl( + + ); + try { + expect( + component.setProps({ ...component.props(), query: { text: 'asssdasdsad' } }) + ).toMatchSnapshot(); + expect(onQueryMatchChange).toHaveBeenCalledWith(false); + expect(onQueryMatchChange).toHaveBeenCalledTimes(1); + } finally { + component.unmount(); + } + }); + + it('renders because query matches the SEARCH_TERMS', () => { + const onQueryMatchChange = jest.fn(); + const telemetryService = new TelemetryService({ + config: { + enabled: true, + url: '', + banner: true, + allowChangingOptInStatus: true, + optIn: false, + optInStatusUrl: '', + sendUsageFrom: 'browser', + }, + reportOptInStatusChange: false, + notifications: coreStart.notifications, + http: coreSetup.http, + }); + + const component = mountWithIntl( + + ); + try { + expect( + component.setProps({ ...component.props(), query: { text: 'TeLEMetry' } }).html() + ).not.toBe(''); // Renders something. + // I can't check against snapshot because of https://github.com/facebook/jest/issues/8618 + // expect(component).toMatchSnapshot(); + + // It should also render if there is no query at all. + expect(component.setProps({ ...component.props(), query: {} }).html()).not.toBe(''); + expect(onQueryMatchChange).toHaveBeenCalledWith(true); + + // Should only be called once because the second time does not change the result + expect(onQueryMatchChange).toHaveBeenCalledTimes(1); + } finally { + component.unmount(); + } + }); + + it('renders null because allowChangingOptInStatus is false', () => { + const onQueryMatchChange = jest.fn(); + const telemetryService = new TelemetryService({ + config: { + enabled: true, + url: '', + banner: true, + allowChangingOptInStatus: false, + optIn: true, + optInStatusUrl: '', + sendUsageFrom: 'browser', + }, + reportOptInStatusChange: false, + notifications: coreStart.notifications, + http: coreSetup.http, + }); + + const component = mountWithIntl( + + ); + try { + expect(component).toMatchSnapshot(); + component.setProps({ ...component.props(), query: { text: 'TeLEMetry' } }); + expect(onQueryMatchChange).toHaveBeenCalledWith(false); + } finally { + component.unmount(); + } + }); + + it('shows the OptInExampleFlyout', () => { + const onQueryMatchChange = jest.fn(); + const telemetryService = new TelemetryService({ + config: { + enabled: true, + url: '', + banner: true, + allowChangingOptInStatus: true, + optIn: false, + optInStatusUrl: '', + sendUsageFrom: 'browser', + }, + reportOptInStatusChange: false, + notifications: coreStart.notifications, + http: coreSetup.http, + }); + + const component = mountWithIntl( + + ); + try { + const toggleExampleComponent = component.find('p > EuiLink[onClick]'); + const updatedView = toggleExampleComponent.simulate('click'); + updatedView.find('OptInExampleFlyout'); + updatedView.simulate('close'); + } finally { + component.unmount(); + } + }); + + it('toggles the OptIn button', async () => { + const onQueryMatchChange = jest.fn(); + const telemetryService = new TelemetryService({ + config: { + enabled: true, + url: '', + banner: true, + allowChangingOptInStatus: true, + optIn: false, + optInStatusUrl: '', + sendUsageFrom: 'browser', + }, + reportOptInStatusChange: false, + notifications: coreStart.notifications, + http: coreSetup.http, + }); + + const component = mountWithIntl( + + ); + try { + const toggleOptInComponent = component.find('Field'); + await expect( + toggleOptInComponent.prop('handleChange')() + ).resolves.toBe(true); + expect((component.state() as any).enabled).toBe(true); + await expect( + toggleOptInComponent.prop('handleChange')() + ).resolves.toBe(true); + expect((component.state() as any).enabled).toBe(false); + telemetryService.setOptIn = jest.fn().mockRejectedValue(Error('test-error')); + await expect( + toggleOptInComponent.prop('handleChange')() + ).rejects.toStrictEqual(Error('test-error')); + } finally { + component.unmount(); + } + }); + + it('test the wrapper (for coverage purposes)', () => { + const onQueryMatchChange = jest.fn(); + const telemetryService = new TelemetryService({ + config: { + enabled: true, + url: '', + banner: true, + allowChangingOptInStatus: false, + optIn: false, + optInStatusUrl: '', + sendUsageFrom: 'browser', + }, + reportOptInStatusChange: false, + notifications: coreStart.notifications, + http: coreSetup.http, + }); + const Wrapper = telemetryManagementSectionWrapper(telemetryService); + expect( + shallowWithIntl( + + ).html() + ).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx index 26e075b666593e..361c5ff719c54e 100644 --- a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx +++ b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx @@ -69,7 +69,9 @@ export class TelemetryManagementSection extends Component { const { query } = nextProps; const searchTerm = (query.text || '').toLowerCase(); - const searchTermMatches = SEARCH_TERMS.some(term => term.indexOf(searchTerm) >= 0); + const searchTermMatches = + this.props.telemetryService.getCanChangeOptInStatus() && + SEARCH_TERMS.some(term => term.indexOf(searchTerm) >= 0); if (searchTermMatches !== this.state.queryMatches) { this.setState( From 8bb67f2c6281c88cc11d95f1e30d61f6c3c8622a Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Wed, 29 Apr 2020 12:00:18 +0200 Subject: [PATCH 04/26] Slim vis type timeseries (#64631) * load visualizations code lazily * load VisEditor lazily --- .../application/components/vis_editor.js | 4 +++ .../components/vis_editor_lazy.tsx | 30 +++++++++++++++++++ .../public/application/editor_controller.js | 2 +- .../vis_type_timeseries/public/metrics_fn.ts | 2 +- .../public/metrics_type.ts | 3 +- 5 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/plugins/vis_type_timeseries/public/application/components/vis_editor_lazy.tsx diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js index 7075e86eb56bf1..9fdb8ccc919b79 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js @@ -240,3 +240,7 @@ VisEditor.propTypes = { timeRange: PropTypes.object, appState: PropTypes.object, }; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { VisEditor as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_editor_lazy.tsx b/src/plugins/vis_type_timeseries/public/application/components/vis_editor_lazy.tsx new file mode 100644 index 00000000000000..d81bd95d8d7710 --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_editor_lazy.tsx @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { lazy, Suspense } from 'react'; +import { EuiLoadingSpinner } from '@elastic/eui'; + +// @ts-ignore +const VisEditorComponent = lazy(() => import('./vis_editor')); + +export const VisEditor = (props: any) => ( + }> + + +); diff --git a/src/plugins/vis_type_timeseries/public/application/editor_controller.js b/src/plugins/vis_type_timeseries/public/application/editor_controller.js index af50d3a06d1fc6..f21b5f947bca79 100644 --- a/src/plugins/vis_type_timeseries/public/application/editor_controller.js +++ b/src/plugins/vis_type_timeseries/public/application/editor_controller.js @@ -21,7 +21,7 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { fetchIndexPatternFields } from './lib/fetch_fields'; import { getSavedObjectsClient, getUISettings, getI18n } from '../services'; -import { VisEditor } from './components/vis_editor'; +import { VisEditor } from './components/vis_editor_lazy'; export class EditorController { constructor(el, vis, eventEmitter, embeddableHandler) { diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index 008b13cce65659..b573225feaab1d 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -20,7 +20,6 @@ import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition, KibanaContext, Render } from '../../expressions/public'; -import { PersistedState } from '../../visualizations/public'; // @ts-ignore import { metricsRequestHandler } from './request_handler'; @@ -76,6 +75,7 @@ export const createMetricsFn = (): ExpressionFunctionDefinition< const params = JSON.parse(args.params); const uiStateParams = JSON.parse(args.uiState); const savedObjectId = args.savedObjectId; + const { PersistedState } = await import('../../visualizations/public'); const uiState = new PersistedState(uiStateParams); const response = await metricsRequestHandler({ diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index c525ce7fa0b3bd..2b0734ceb4d4d5 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -25,6 +25,7 @@ import { EditorController } from './application'; // @ts-ignore import { PANEL_TYPES } from '../common/panel_types'; import { defaultFeedbackMessage } from '../../kibana_utils/public'; +import { VisEditor } from './application/components/vis_editor_lazy'; export const metricsVisDefinition = { name: 'metrics', @@ -69,7 +70,7 @@ export const metricsVisDefinition = { show_legend: 1, show_grid: 1, }, - component: require('./application/components/vis_editor').VisEditor, + component: VisEditor, }, editor: EditorController, options: { From 05f0d0ac8a067d3dade466deaaaa35a0d7e18503 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Wed, 29 Apr 2020 07:28:03 -0400 Subject: [PATCH 05/26] [Uptime] Migrate client to New Platform (#55086) * Move uptime legacy server to plugins directory. * Re-add feature registration code. * Move uptime legacy server to plugins directory. * Re-add feature registration code. * Move all files. * WIP fixing things. * WIP fixing things. * WIP fixing things. * Finished fixing server. * Fix alert type registration glitch. * Remove obsolete file. * Fix unwanted revisions, uncomment previously un-migrated code, delete accidentally-merged files. * More cleanup. * Fix all non-maps unit tests. * Get functional tests working. * Delete misplaced file. * Add uptime CODEOWNERS entry. * Get map working in Uptime app on NP. * Update CODEOWNERS to remove legacy entry. * Update server imports. * Delete and clean up unused or redundant code/comments. * Move new files from legacy to NP to fix merge error. * Fix broken import. * Delete obsolete test snapshots. * Clean up imports and types, delete obsolete code. * Clean up redundant common imports. * Delete obsolete translation keys. * Add additional explicit typing to plugin class. * Combine redundant common imports. * Delete unneeded optionalPlugin entry. * Revert "Combine redundant common imports." This reverts commit 159e66c349340ba1ede9940c8c3fb980e7be4586. * Update a translation description. * Revert "Clean up redundant common imports." This reverts commit 8794013fbeef776c6abdb504e10da1c17796c651. * Remove new common index file and revert imports from only common to more specific paths. * Fix broken imports in `~/x-pack/test`. * Move new file from legacy to NP location. Co-authored-by: Elastic Machine --- .github/CODEOWNERS | 1 - x-pack/.i18nrc.json | 2 +- x-pack/index.js | 2 - .../plugins/uptime/common/graphql/types.ts | 0 x-pack/legacy/plugins/uptime/index.ts | 36 ---------- .../plugins/uptime/public/apps/index.ts | 16 ----- .../plugins/uptime/public/apps/plugin.ts | 56 --------------- .../plugins/uptime/public/register_feature.ts | 25 ------- x-pack/legacy/plugins/uptime/tsconfig.json | 7 -- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - x-pack/{legacy => }/plugins/uptime/README.md | 0 .../plugins/uptime/common/constants/alerts.ts | 0 .../uptime/common/constants/capabilities.ts | 0 .../common/constants/chart_format_limits.ts | 0 .../common/constants/client_defaults.ts | 0 .../common/constants/context_defaults.ts | 0 .../plugins/uptime/common/constants/index.ts | 0 .../plugins/uptime/common/constants/plugin.ts | 9 ++- .../plugins/uptime/common/constants/query.ts | 0 .../uptime/common/constants/rest_api.ts | 0 .../common/constants/settings_defaults.ts | 0 .../plugins/uptime/common/constants/ui.ts | 0 .../common/runtime_types/alerts/index.ts | 0 .../runtime_types/alerts/status_check.ts | 0 .../uptime/common/runtime_types/certs.ts | 0 .../uptime/common/runtime_types/common.ts | 0 .../common/runtime_types/dynamic_settings.ts | 0 .../uptime/common/runtime_types/index.ts | 2 +- .../common/runtime_types/monitor/details.ts | 0 .../common/runtime_types/monitor/index.ts | 0 .../common/runtime_types/monitor/locations.ts | 0 .../common/runtime_types/monitor/state.ts | 0 .../runtime_types/overview_filters/index.ts | 0 .../overview_filters/overview_filters.ts | 0 .../common/runtime_types/ping/histogram.ts | 0 .../uptime/common/runtime_types/ping/index.ts | 0 .../uptime/common/runtime_types/ping/ping.ts | 0 .../common/runtime_types/snapshot/index.ts | 0 .../runtime_types/snapshot/snapshot_count.ts | 0 .../plugins/uptime/common/types/index.ts | 12 ---- x-pack/plugins/uptime/kibana.json | 12 +++- .../{legacy => }/plugins/uptime/public/app.ts | 0 .../uptime/public/apps/index.ts} | 8 +-- x-pack/plugins/uptime/public/apps/plugin.ts | 72 +++++++++++++++++++ .../plugins/uptime/public/apps/template.html | 0 .../plugins/uptime/public/badge.ts | 0 .../plugins/uptime/public/breadcrumbs.ts | 0 .../__snapshots__/location_link.test.tsx.snap | 0 .../uptime_date_picker.test.tsx.snap | 0 .../common/__tests__/location_link.test.tsx | 0 .../__tests__/uptime_date_picker.test.tsx | 0 .../chart_empty_state.test.tsx.snap | 0 .../__snapshots__/chart_wrapper.test.tsx.snap | 0 .../__snapshots__/donut_chart.test.tsx.snap | 0 .../donut_chart_legend.test.tsx.snap | 0 .../donut_chart_legend_row.test.tsx.snap | 0 .../duration_charts.test.tsx.snap | 0 .../monitor_bar_series.test.tsx.snap | 0 .../ping_histogram.test.tsx.snap | 0 .../__tests__/chart_empty_state.test.tsx | 0 .../charts/__tests__/chart_wrapper.test.tsx | 0 .../charts/__tests__/donut_chart.test.tsx | 0 .../__tests__/donut_chart_legend.test.tsx | 0 .../__tests__/donut_chart_legend_row.test.tsx | 0 .../charts/__tests__/duration_charts.test.tsx | 0 .../charts/__tests__/get_tick_format.test.ts | 0 .../__tests__/monitor_bar_series.test.tsx | 0 .../charts/__tests__/ping_histogram.test.tsx | 0 .../common/charts/annotation_tooltip.tsx | 0 .../common/charts/chart_empty_state.tsx | 0 .../charts/chart_wrapper/chart_wrapper.tsx | 0 .../common/charts/chart_wrapper/index.ts | 0 .../components/common/charts/donut_chart.tsx | 0 .../common/charts/donut_chart_legend.tsx | 0 .../common/charts/donut_chart_legend_row.tsx | 0 .../common/charts/duration_chart.tsx | 0 .../common/charts/duration_line_bar_list.tsx | 4 +- .../charts/duration_line_series_list.tsx | 0 .../common/charts/get_tick_format.ts | 0 .../public/components/common/charts/index.ts | 0 .../common/charts/monitor_bar_series.tsx | 0 .../common/charts/ping_histogram.tsx | 0 .../responsive_wrapper.test.tsx.snap | 0 .../__tests__/responsive_wrapper.test.tsx | 0 .../components/common/higher_order/index.ts | 0 .../higher_order/responsive_wrapper.tsx | 0 .../components/common/location_link.tsx | 0 .../components/common/uptime_date_picker.tsx | 0 .../monitor_charts.test.tsx.snap | 0 .../monitor/__tests__/monitor_charts.test.tsx | 0 .../uptime/public/components/monitor/index.ts | 0 .../__snapshots__/location_map.test.tsx.snap | 0 .../location_missing.test.tsx.snap | 0 .../location_status_tags.test.tsx.snap | 0 .../__tests__/location_map.test.tsx | 0 .../__tests__/location_missing.test.tsx | 0 .../__tests__/location_status_tags.test.tsx | 0 .../embeddables/__tests__/__mocks__/mock.ts | 0 .../embeddables/__tests__/map_config.test.ts | 0 .../location_map/embeddables/embedded_map.tsx | 32 ++++----- .../embeddables/low_poly_layer.json | 0 .../location_map/embeddables/map_config.ts | 0 .../location_map/embeddables/translations.ts | 0 .../components/monitor/location_map/index.ts} | 0 .../monitor/location_map/location_map.tsx | 0 .../monitor/location_map/location_missing.tsx | 0 .../location_map/location_status_tags.tsx | 0 .../confirm_delete.test.tsx.snap | 0 .../__snapshots__/license_info.test.tsx.snap | 0 .../__snapshots__/ml_flyout.test.tsx.snap | 0 .../ml_integerations.test.tsx.snap | 0 .../__snapshots__/ml_job_link.test.tsx.snap | 0 .../__snapshots__/ml_manage_job.test.tsx.snap | 0 .../ml/__tests__/confirm_delete.test.tsx | 0 .../ml/__tests__/license_info.test.tsx | 0 .../monitor/ml/__tests__/ml_flyout.test.tsx | 2 +- .../ml/__tests__/ml_integerations.test.tsx | 0 .../monitor/ml/__tests__/ml_job_link.test.tsx | 0 .../ml/__tests__/ml_manage_job.test.tsx | 0 .../components/monitor/ml/confirm_delete.tsx | 0 .../public/components/monitor/ml/index.ts | 0 .../components/monitor/ml/license_info.tsx | 0 .../components/monitor/ml/manage_ml_job.tsx | 0 .../components/monitor/ml/ml_flyout.tsx | 0 .../monitor/ml/ml_flyout_container.tsx | 2 +- .../components/monitor/ml/ml_integeration.tsx | 4 +- .../components/monitor/ml/ml_job_link.tsx | 0 .../components/monitor/ml/translations.tsx | 0 .../components/monitor/monitor_charts.tsx | 0 .../monitor/monitor_duration/index.ts | 0 .../monitor_duration/monitor_duration.tsx | 0 .../monitor_duration_container.tsx | 2 +- .../monitor_ssl_certificate.test.tsx.snap | 0 .../monitor_status.bar.test.tsx.snap | 0 .../status_by_location.test.tsx.snap | 0 .../__test__/monitor_ssl_certificate.test.tsx | 0 .../__test__/monitor_status.bar.test.tsx | 0 .../__test__/status_by_location.test.tsx | 0 .../monitor/monitor_status_details/index.ts | 0 .../monitor_status_bar/index.ts | 0 .../monitor_status_bar/ssl_certificate.tsx | 0 .../monitor_status_bar/status_bar.tsx | 0 .../status_bar_container.tsx | 0 .../monitor_status_bar/status_by_location.tsx | 0 .../monitor_status_bar/translations.ts | 0 .../monitor_status_details/status_details.tsx | 0 .../status_details_container.tsx | 0 .../monitor_status_details/translations.ts | 0 .../monitor/ping_histogram/index.ts | 0 .../ping_histogram_container.tsx | 0 .../__snapshots__/doc_link_body.test.tsx.snap | 0 .../__snapshots__/expanded_row.test.tsx.snap | 0 .../__snapshots__/ping_list.test.tsx.snap | 0 .../__tests__/doc_link_body.test.tsx | 0 .../ping_list/__tests__/expanded_row.test.tsx | 0 .../ping_list/__tests__/ping_list.test.tsx | 0 .../monitor/ping_list/doc_link_body.tsx | 0 .../monitor/ping_list/expanded_row.tsx | 0 .../components/monitor/ping_list/index.tsx | 0 .../monitor/ping_list/location_name.tsx | 0 .../monitor/ping_list/ping_list.tsx | 0 .../monitor/ping_list/ping_list_container.tsx | 0 .../parsing_error_callout.test.tsx.snap | 0 .../__snapshots__/snapshot.test.tsx.snap | 0 .../snapshot_heading.test.tsx.snap | 0 .../__tests__/parsing_error_callout.test.tsx | 0 .../overview/__tests__/snapshot.test.tsx | 0 .../__tests__/snapshot_heading.test.tsx | 0 .../__tests__/alert_monitor_status.test.tsx | 0 .../overview/alerts/alert_monitor_status.tsx | 0 .../alert_monitor_status.tsx | 0 .../alerts/alerts_containers/index.ts | 0 .../toggle_alert_flyout_button.tsx | 0 .../uptime_alerts_flyout_wrapper.tsx | 0 .../components/overview/alerts/index.ts | 0 .../alerts/toggle_alert_flyout_button.tsx | 2 +- .../alerts/uptime_alerts_context_provider.tsx | 4 +- .../alerts/uptime_alerts_flyout_wrapper.tsx | 2 +- .../data_or_index_missing.test.tsx.snap | 0 .../__snapshots__/empty_state.test.tsx.snap | 0 .../__tests__/data_or_index_missing.test.tsx | 0 .../__tests__/empty_state.test.tsx | 0 .../empty_state/data_or_index_missing.tsx | 0 .../overview/empty_state/empty_state.tsx | 2 +- .../empty_state/empty_state_container.tsx | 0 .../empty_state/empty_state_error.tsx | 2 +- .../empty_state/empty_state_loading.tsx | 0 .../components/overview/empty_state/index.ts | 0 .../filter_popover.test.tsx.snap | 0 .../filter_status_button.test.tsx.snap | 0 .../parse_filter_map.test.ts.snap | 0 .../__tests__/filter_popover.test.tsx | 0 .../__tests__/filter_status_button.test.tsx | 0 .../__tests__/parse_filter_map.test.ts | 0 .../__tests__/toggle_selected_item.test.ts | 0 .../overview/filter_group/filter_group.tsx | 0 .../filter_group/filter_group_container.tsx | 0 .../overview/filter_group/filter_popover.tsx | 0 .../filter_group/filter_status_button.tsx | 0 .../components/overview/filter_group/index.ts | 0 .../overview/filter_group/parse_filter_map.ts | 0 .../filter_group/toggle_selected_item.ts | 0 .../filter_group/uptime_filter_button.tsx | 0 .../public/components/overview/index.ts | 0 .../components/overview/kuery_bar/index.ts | 0 .../overview/kuery_bar/kuery_bar.tsx | 2 +- .../kuery_bar/kuery_bar_container.tsx | 0 .../kuery_bar/typeahead/click_outside.js | 0 .../overview/kuery_bar/typeahead/index.d.ts | 0 .../overview/kuery_bar/typeahead/index.js | 0 .../kuery_bar/typeahead/suggestion.js | 2 +- .../kuery_bar/typeahead/suggestions.js | 2 +- .../__snapshots__/monitor_list.test.tsx.snap | 0 .../monitor_list_status_column.test.tsx.snap | 0 .../monitor_page_link.test.tsx.snap | 0 .../__tests__/monitor_list.test.tsx | 0 .../monitor_list_page_size_select.test.tsx | 0 .../monitor_list_status_column.test.tsx | 0 .../__tests__/monitor_page_link.test.tsx | 0 .../__tests__/parse_timestamp.test.ts | 0 .../components/overview/monitor_list/index.ts | 0 .../overview/monitor_list/monitor_list.tsx | 6 -- .../monitor_list/monitor_list_container.tsx | 2 +- .../integration_group.test.tsx.snap | 0 .../integration_link.test.tsx.snap | 0 .../monitor_list_drawer.test.tsx.snap | 0 .../monitor_status_list.test.tsx.snap | 0 .../monitor_status_row.test.tsx.snap | 0 .../most_recent_error.test.tsx.snap | 0 .../monitor_list_drawer/__tests__/data.json | 0 .../__tests__/integration_group.test.tsx | 0 .../__tests__/integration_link.test.tsx | 0 .../__tests__/monitor_list_drawer.test.tsx | 0 .../__tests__/monitor_status_list.test.tsx | 0 .../__tests__/monitor_status_row.test.tsx | 0 .../__tests__/most_recent_error.test.tsx | 0 .../actions_popover/actions_popover.tsx | 0 .../actions_popover_container.tsx | 0 .../actions_popover/integration_group.tsx | 0 .../actions_popover/integration_link.tsx | 0 .../monitor_list/monitor_list_drawer/index.ts | 0 .../list_drawer_container.tsx | 0 .../monitor_list_drawer.tsx | 0 .../monitor_status_list.tsx | 0 .../monitor_status_row.tsx | 0 .../monitor_list_drawer/most_recent_error.tsx | 0 .../monitor_list_page_size_select.tsx | 0 .../monitor_list_status_column.tsx | 0 .../monitor_list/monitor_page_link.tsx | 0 .../monitor_list/overview_page_link.tsx | 0 .../overview/monitor_list/parse_timestamp.ts | 0 .../overview/monitor_list/translations.ts | 0 .../components/overview/monitor_list/types.ts | 0 .../overview/overview_container.tsx | 0 .../overview/parsing_error_callout.tsx | 0 .../components/overview/snapshot/index.ts | 0 .../components/overview/snapshot/snapshot.tsx | 0 .../overview/snapshot/snapshot_container.tsx | 0 .../overview/snapshot/snapshot_heading.tsx | 0 .../components/overview/status_panel.tsx | 0 .../certificate_form.test.tsx.snap | 0 .../__snapshots__/indices_form.test.tsx.snap | 0 .../__tests__/certificate_form.test.tsx | 0 .../settings/__tests__/indices_form.test.tsx | 0 .../components/settings/certificate_form.tsx | 0 .../components/settings/indices_form.tsx | 0 .../plugins/uptime/public/contexts/index.ts | 4 ++ .../contexts/uptime_refresh_context.tsx | 0 .../contexts/uptime_settings_context.tsx | 2 +- .../uptime_startup_plugins_context.tsx | 15 ++++ .../public/contexts/uptime_theme_context.tsx | 0 .../use_url_params.test.tsx.snap | 0 .../hooks/__tests__/use_breadcrumbs.test.tsx | 2 +- .../hooks/__tests__/use_url_params.test.tsx | 0 .../plugins/uptime/public/hooks/index.ts | 0 .../public/hooks/update_kuery_string.ts | 2 +- .../uptime/public/hooks/use_breadcrumbs.ts | 2 +- .../uptime/public/hooks/use_monitor.ts | 0 .../uptime/public/hooks/use_telemetry.ts | 0 .../uptime/public/hooks/use_url_params.ts | 0 .../uptime/public/icons/heartbeat_white.svg | 0 x-pack/plugins/uptime/public/index.ts | 11 +++ .../framework/capabilities_adapter.ts | 0 .../framework/new_platform_adapter.tsx | 17 +++-- .../__tests__/monitor_status.test.ts | 0 .../uptime/public/lib/alert_types/index.ts | 4 +- .../public/lib/alert_types/monitor_status.tsx | 9 +-- .../stringify_kueries.test.ts.snap | 0 .../stringify_url_params.test.ts.snap | 0 .../combine_filters_and_user_search.test.ts | 0 .../__tests__/convert_measurements.test.ts | 0 .../__tests__/series_has_down_values.test.ts | 0 .../__tests__/stringify_kueries.test.ts | 0 .../__tests__/stringify_url_params.test.ts | 0 .../charts/__tests__/get_label_format.test.ts | 0 .../__tests__/is_within_current_date.test.ts | 0 .../lib/helper/charts/get_chart_date_label.ts | 0 .../lib/helper/charts/get_label_format.ts | 0 .../uptime/public/lib/helper/charts/index.ts | 0 .../helper/charts/is_within_current_date.ts | 0 .../helper/combine_filters_and_user_search.ts | 0 .../public/lib/helper/convert_measurements.ts | 0 .../uptime/public/lib/helper/get_title.ts | 0 .../public/lib/helper/helper_with_router.tsx | 0 .../plugins/uptime/public/lib/helper/index.ts | 0 .../__tests__/get_apm_href.test.ts | 0 .../__tests__/get_infra_href.test.ts | 0 .../__tests__/get_logging_href.test.ts | 0 .../add_base_path.ts | 0 .../observability_integration/build_href.ts | 0 .../observability_integration/get_apm_href.ts | 0 .../get_infra_href.ts | 0 .../get_logging_href.ts | 0 .../helper/observability_integration/index.ts | 0 .../lib/helper/series_has_down_values.ts | 0 .../public/lib/helper/stringify_kueries.ts | 0 .../public/lib/helper/stringify_url_params.ts | 0 .../get_supported_url_params.test.ts.snap | 0 .../get_supported_url_params.test.ts | 0 .../__tests__/parse_absolute_date.test.ts | 0 .../parse_autorefresh_interval.test.ts} | 0 .../__tests__/parse_is_paused.test.ts | 0 .../__tests__/parse_url_int.test.ts | 24 +++++++ .../url_params/get_supported_url_params.ts | 0 .../public/lib/helper/url_params/index.ts | 0 .../helper/url_params/parse_absolute_date.ts | 0 .../lib/helper/url_params/parse_is_paused.ts | 0 .../lib/helper/url_params/parse_url_int.ts | 1 - .../plugins/uptime/public/lib/index.ts | 0 .../plugins/uptime/public/lib/lib.ts | 0 .../__snapshots__/monitor.test.tsx.snap | 0 .../__snapshots__/not_found.test.tsx.snap | 0 .../__snapshots__/overview.test.tsx.snap | 0 .../__snapshots__/page_header.test.tsx.snap | 0 .../public/pages/__tests__/monitor.test.tsx | 0 .../public/pages/__tests__/not_found.test.tsx | 0 .../public/pages/__tests__/overview.test.tsx | 0 .../pages/__tests__/page_header.test.tsx | 0 .../plugins/uptime/public/pages/index.ts | 0 .../plugins/uptime/public/pages/monitor.tsx | 5 +- .../plugins/uptime/public/pages/not_found.tsx | 0 .../plugins/uptime/public/pages/overview.tsx | 6 +- .../uptime/public/pages/page_header.tsx | 0 .../plugins/uptime/public/pages/settings.tsx | 2 +- .../uptime/public/pages/translations.ts | 0 .../plugins/uptime/public/routes.tsx | 2 +- .../overview_filters.test.ts.snap | 0 .../__tests__/overview_filters.test.ts | 0 .../public/state/actions/dynamic_settings.ts | 0 .../uptime/public/state/actions/index.ts | 0 .../public/state/actions/index_patternts.ts | 0 .../public/state/actions/index_status.ts | 0 .../uptime/public/state/actions/ml_anomaly.ts | 6 +- .../uptime/public/state/actions/monitor.ts | 0 .../public/state/actions/monitor_duration.ts | 2 +- .../public/state/actions/monitor_list.ts | 0 .../public/state/actions/monitor_status.ts | 0 .../public/state/actions/overview_filters.ts | 0 .../uptime/public/state/actions/ping.ts | 0 .../uptime/public/state/actions/snapshot.ts | 0 .../uptime/public/state/actions/types.ts | 2 +- .../plugins/uptime/public/state/actions/ui.ts | 0 .../uptime/public/state/actions/utils.ts | 2 +- .../__snapshots__/snapshot.test.ts.snap | 0 .../state/api/__tests__/ml_anomaly.test.ts | 0 .../state/api/__tests__/snapshot.test.ts | 0 .../public/state/api/dynamic_settings.ts | 0 .../plugins/uptime/public/state/api/index.ts | 0 .../uptime/public/state/api/index_pattern.ts | 0 .../uptime/public/state/api/index_status.ts | 0 .../uptime/public/state/api/ml_anomaly.ts | 6 +- .../uptime/public/state/api/monitor.ts | 0 .../public/state/api/monitor_duration.ts | 0 .../uptime/public/state/api/monitor_list.ts | 0 .../uptime/public/state/api/monitor_status.ts | 0 .../public/state/api/overview_filters.ts | 0 .../plugins/uptime/public/state/api/ping.ts | 0 .../uptime/public/state/api/snapshot.ts | 0 .../plugins/uptime/public/state/api/types.ts | 0 .../plugins/uptime/public/state/api/utils.ts | 2 +- .../effects/__tests__/fetch_effect.test.ts | 0 .../public/state/effects/dynamic_settings.ts | 0 .../public/state/effects/fetch_effect.ts | 2 +- .../uptime/public/state/effects/index.ts | 0 .../public/state/effects/index_pattern.ts | 0 .../public/state/effects/index_status.ts | 0 .../uptime/public/state/effects/ml_anomaly.ts | 0 .../uptime/public/state/effects/monitor.ts | 0 .../public/state/effects/monitor_duration.ts | 0 .../public/state/effects/monitor_list.ts | 0 .../public/state/effects/monitor_status.ts | 0 .../public/state/effects/overview_filters.ts | 0 .../uptime/public/state/effects/ping.ts | 0 .../uptime/public/state/effects/snapshot.ts | 0 .../plugins/uptime/public/state/index.ts | 0 .../uptime/public/state/kibana_service.ts | 0 .../__snapshots__/snapshot.test.ts.snap | 0 .../__tests__/__snapshots__/ui.test.ts.snap | 0 .../state/reducers/__tests__/snapshot.test.ts | 0 .../state/reducers/__tests__/ui.test.ts | 0 .../public/state/reducers/dynamic_settings.ts | 0 .../uptime/public/state/reducers/index.ts | 0 .../public/state/reducers/index_pattern.ts | 2 +- .../public/state/reducers/index_status.ts | 0 .../public/state/reducers/ml_anomaly.ts | 6 +- .../uptime/public/state/reducers/monitor.ts | 0 .../public/state/reducers/monitor_duration.ts | 0 .../public/state/reducers/monitor_list.ts | 0 .../public/state/reducers/monitor_status.ts | 0 .../public/state/reducers/overview_filters.ts | 0 .../uptime/public/state/reducers/ping.ts | 0 .../uptime/public/state/reducers/ping_list.ts | 0 .../uptime/public/state/reducers/snapshot.ts | 0 .../uptime/public/state/reducers/types.ts | 2 +- .../uptime/public/state/reducers/ui.ts | 0 .../uptime/public/state/reducers/utils.ts | 0 .../state/selectors/__tests__/index.test.ts | 0 .../uptime/public/state/selectors/index.ts | 0 .../plugins/uptime/public/uptime_app.tsx | 34 +++++---- x-pack/plugins/uptime/server/kibana.index.ts | 2 +- .../lib/adapters/framework/adapter_types.ts | 4 +- .../framework/kibana_framework_adapter.ts | 4 +- .../lib/alerts/__tests__/status_check.test.ts | 6 +- .../uptime/server/lib/alerts/status_check.ts | 4 +- .../lib/helper/get_histogram_interval.ts | 2 +- .../lib/requests/__tests__/get_certs.test.ts | 2 +- .../__tests__/get_latest_monitor.test.ts | 2 +- .../__tests__/get_monitor_charts.test.ts | 2 +- .../__tests__/get_monitor_status.test.ts | 2 +- .../__tests__/get_ping_histogram.test.ts | 2 +- .../lib/requests/__tests__/get_pings.test.ts | 2 +- .../uptime/server/lib/requests/get_certs.ts | 2 +- .../server/lib/requests/get_filter_bar.ts | 2 +- .../server/lib/requests/get_index_status.ts | 2 +- .../server/lib/requests/get_latest_monitor.ts | 2 +- .../lib/requests/get_monitor_details.ts | 5 +- .../lib/requests/get_monitor_duration.ts | 7 +- .../lib/requests/get_monitor_locations.ts | 7 +- .../server/lib/requests/get_monitor_states.ts | 9 +-- .../server/lib/requests/get_ping_histogram.ts | 7 +- .../uptime/server/lib/requests/get_pings.ts | 2 +- .../lib/requests/get_snapshot_counts.ts | 4 +- .../search/__tests__/fetch_page.test.ts | 2 +- .../search/__tests__/query_context.test.ts | 5 +- .../requests/search/__tests__/test_helpers.ts | 5 +- .../requests/search/enrich_monitor_groups.ts | 4 +- .../server/lib/requests/search/fetch_page.ts | 8 +-- .../requests/search/find_potential_matches.ts | 2 +- .../requests/search/monitor_group_iterator.ts | 2 +- .../search/refine_potential_matches.ts | 2 +- .../server/lib/requests/search/types.ts | 5 +- .../server/lib/requests/uptime_requests.ts | 22 +++--- .../uptime/server/lib/saved_objects.ts | 4 +- x-pack/plugins/uptime/server/plugin.ts | 11 +-- .../plugins/uptime/server/rest_api/certs.ts | 2 +- .../server/rest_api/dynamic_settings.ts | 5 +- .../rest_api/index_state/get_index_pattern.ts | 2 +- .../rest_api/index_state/get_index_status.ts | 2 +- .../server/rest_api/monitors/monitor_list.ts | 3 +- .../rest_api/monitors/monitor_locations.ts | 2 +- .../rest_api/monitors/monitor_status.ts | 2 +- .../rest_api/monitors/monitors_details.ts | 2 +- .../rest_api/monitors/monitors_durations.ts | 2 +- .../overview_filters/get_overview_filters.ts | 2 +- .../rest_api/pings/get_ping_histogram.ts | 2 +- .../uptime/server/rest_api/pings/get_pings.ts | 4 +- .../rest_api/snapshot/get_snapshot_count.ts | 2 +- .../rest_api/telemetry/log_page_view.ts | 2 +- .../plugins/uptime/server/rest_api/types.ts | 4 +- .../apis/uptime/feature_controls.ts | 2 +- .../api_integration/apis/uptime/rest/certs.ts | 4 +- .../apis/uptime/rest/doc_count.ts | 2 +- .../apis/uptime/rest/dynamic_settings.ts | 5 +- .../uptime/rest/monitor_states_generated.ts | 4 +- .../uptime/rest/monitor_states_real_data.ts | 4 +- .../apis/uptime/rest/ping_list.ts | 2 +- .../apis/uptime/rest/telemetry_collectors.ts | 2 +- .../test/functional/apps/uptime/settings.ts | 4 +- .../functional/services/uptime/settings.ts | 2 +- 480 files changed, 331 insertions(+), 401 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/common/graphql/types.ts delete mode 100644 x-pack/legacy/plugins/uptime/index.ts delete mode 100644 x-pack/legacy/plugins/uptime/public/apps/index.ts delete mode 100644 x-pack/legacy/plugins/uptime/public/apps/plugin.ts delete mode 100644 x-pack/legacy/plugins/uptime/public/register_feature.ts delete mode 100644 x-pack/legacy/plugins/uptime/tsconfig.json rename x-pack/{legacy => }/plugins/uptime/README.md (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/alerts.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/capabilities.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/chart_format_limits.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/client_defaults.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/context_defaults.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/plugin.ts (64%) rename x-pack/{legacy => }/plugins/uptime/common/constants/query.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/rest_api.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/settings_defaults.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/constants/ui.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/alerts/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/alerts/status_check.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/certs.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/common.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/dynamic_settings.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/monitor/details.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/monitor/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/monitor/locations.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/monitor/state.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/overview_filters/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/overview_filters/overview_filters.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/ping/histogram.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/ping/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/ping/ping.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/snapshot/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/runtime_types/snapshot/snapshot_count.ts (100%) rename x-pack/{legacy => }/plugins/uptime/common/types/index.ts (69%) rename x-pack/{legacy => }/plugins/uptime/public/app.ts (100%) rename x-pack/{legacy/plugins/uptime/common/graphql/resolver_types.ts => plugins/uptime/public/apps/index.ts} (56%) create mode 100644 x-pack/plugins/uptime/public/apps/plugin.ts rename x-pack/{legacy => }/plugins/uptime/public/apps/template.html (100%) rename x-pack/{legacy => }/plugins/uptime/public/badge.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/breadcrumbs.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/__tests__/__snapshots__/location_link.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/__tests__/location_link.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/__tests__/uptime_date_picker.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/monitor_bar_series.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/ping_histogram.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/chart_empty_state.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/chart_wrapper.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/donut_chart.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend_row.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/duration_charts.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/get_tick_format.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/monitor_bar_series.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/annotation_tooltip.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/chart_empty_state.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/chart_wrapper/chart_wrapper.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/chart_wrapper/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/donut_chart.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/donut_chart_legend_row.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/duration_chart.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx (94%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/duration_line_series_list.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/get_tick_format.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/monitor_bar_series.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/charts/ping_histogram.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/higher_order/__tests__/responsive_wrapper.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/higher_order/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/higher_order/responsive_wrapper.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/location_link.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/common/uptime_date_picker.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/__tests__/__snapshots__/monitor_charts.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/__tests__/monitor_charts.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_map.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/__tests__/location_map.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/__tests__/location_missing.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/__tests__/location_status_tags.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/__mocks__/mock.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/map_config.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx (85%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/embeddables/low_poly_layer.json (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/embeddables/map_config.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/embeddables/translations.ts (100%) rename x-pack/{legacy/plugins/uptime/public/components/monitor/location_map/index.tsx => plugins/uptime/public/components/monitor/location_map/index.ts} (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/location_map.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/location_missing.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/location_map/location_status_tags.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/license_info.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/confirm_delete.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/license_info.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx (97%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/ml_integerations.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/ml_job_link.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/__tests__/ml_manage_job.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/confirm_delete.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/license_info.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/ml_flyout.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx (98%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx (95%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/ml_job_link.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ml/translations.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_charts.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_duration/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx (96%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_ssl_certificate.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_status.bar.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/status_by_location.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_ssl_certificate.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_status.bar.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/__test__/status_by_location.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/ssl_certificate.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_by_location.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/translations.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/status_details.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/status_details_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/monitor_status_details/translations.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_histogram/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_histogram/ping_histogram_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/__tests__/doc_link_body.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/__tests__/expanded_row.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/__tests__/ping_list.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/doc_link_body.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/expanded_row.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/index.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/location_name.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/monitor/ping_list/ping_list_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/__tests__/__snapshots__/parsing_error_callout.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot_heading.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/__tests__/parsing_error_callout.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/__tests__/snapshot.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/__tests__/snapshot_heading.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/__tests__/alert_monitor_status.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/alert_monitor_status.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/alerts_containers/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx (97%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx (83%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx (90%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/__tests__/data_or_index_missing.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/data_or_index_missing.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/empty_state.tsx (96%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx (95%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/empty_state_loading.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/empty_state/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/__tests__/filter_popover.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/__tests__/filter_status_button.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/__tests__/parse_filter_map.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/__tests__/toggle_selected_item.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/filter_group.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/filter_group_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/filter_popover.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/filter_status_button.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/toggle_selected_item.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/filter_group/uptime_filter_button.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/kuery_bar/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx (98%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/kuery_bar/kuery_bar_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/kuery_bar/typeahead/click_outside.js (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.d.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.js (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js (97%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js (95%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_page_size_select.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_status_column.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_page_link.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/__tests__/parse_timestamp.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx (96%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx (95%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/data.json (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_link.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/list_drawer_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_row.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_page_size_select.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/monitor_page_link.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/overview_page_link.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/parse_timestamp.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/translations.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/monitor_list/types.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/overview_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/parsing_error_callout.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/snapshot/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/snapshot/snapshot.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/snapshot/snapshot_container.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/snapshot/snapshot_heading.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/overview/status_panel.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/settings/certificate_form.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/components/settings/indices_form.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/contexts/index.ts (82%) rename x-pack/{legacy => }/plugins/uptime/public/contexts/uptime_refresh_context.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/contexts/uptime_settings_context.tsx (96%) create mode 100644 x-pack/plugins/uptime/public/contexts/uptime_startup_plugins_context.tsx rename x-pack/{legacy => }/plugins/uptime/public/contexts/uptime_theme_context.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx (95%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/update_kuery_string.ts (95%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/use_breadcrumbs.ts (94%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/use_monitor.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/use_telemetry.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/hooks/use_url_params.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/icons/heartbeat_white.svg (100%) create mode 100644 x-pack/plugins/uptime/public/index.ts rename x-pack/{legacy => }/plugins/uptime/public/lib/adapters/framework/capabilities_adapter.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx (86%) rename x-pack/{legacy => }/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/alert_types/index.ts (67%) rename x-pack/{legacy => }/plugins/uptime/public/lib/alert_types/monitor_status.tsx (88%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_kueries.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_url_params.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/__tests__/combine_filters_and_user_search.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/__tests__/convert_measurements.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/__tests__/stringify_kueries.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/__tests__/stringify_url_params.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/charts/__tests__/get_label_format.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/charts/__tests__/is_within_current_date.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/charts/get_label_format.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/charts/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/charts/is_within_current_date.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/combine_filters_and_user_search.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/convert_measurements.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/get_title.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/helper_with_router.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_apm_href.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_infra_href.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_logging_href.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/add_base_path.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/build_href.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/get_infra_href.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/get_logging_href.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/observability_integration/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/series_has_down_values.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/stringify_kueries.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/stringify_url_params.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/__tests__/__snapshots__/get_supported_url_params.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/__tests__/get_supported_url_params.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts (100%) rename x-pack/{legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_url_int.test.ts => plugins/uptime/public/lib/helper/url_params/__tests__/parse_autorefresh_interval.test.ts} (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/__tests__/parse_is_paused.test.ts (100%) create mode 100644 x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_url_int.test.ts rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/parse_is_paused.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/helper/url_params/parse_url_int.ts (87%) rename x-pack/{legacy => }/plugins/uptime/public/lib/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/lib/lib.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/__tests__/__snapshots__/not_found.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/__tests__/__snapshots__/overview.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/__tests__/monitor.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/__tests__/not_found.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/__tests__/overview.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/__tests__/page_header.test.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/monitor.tsx (87%) rename x-pack/{legacy => }/plugins/uptime/public/pages/not_found.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/overview.tsx (96%) rename x-pack/{legacy => }/plugins/uptime/public/pages/page_header.tsx (100%) rename x-pack/{legacy => }/plugins/uptime/public/pages/settings.tsx (98%) rename x-pack/{legacy => }/plugins/uptime/public/pages/translations.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/routes.tsx (93%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/__tests__/overview_filters.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/dynamic_settings.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/index_patternts.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/index_status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/ml_anomaly.ts (82%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/monitor.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/monitor_duration.ts (90%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/monitor_list.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/monitor_status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/overview_filters.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/ping.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/snapshot.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/types.ts (94%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/ui.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/actions/utils.ts (90%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/__tests__/__snapshots__/snapshot.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/__tests__/ml_anomaly.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/__tests__/snapshot.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/dynamic_settings.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/index_pattern.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/index_status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/ml_anomaly.ts (92%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/monitor.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/monitor_duration.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/monitor_list.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/monitor_status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/overview_filters.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/ping.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/snapshot.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/types.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/api/utils.ts (95%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/__tests__/fetch_effect.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/dynamic_settings.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/fetch_effect.ts (94%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/index_pattern.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/index_status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/ml_anomaly.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/monitor.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/monitor_duration.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/monitor_list.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/monitor_status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/overview_filters.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/ping.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/effects/snapshot.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/kibana_service.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/__tests__/__snapshots__/snapshot.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/__tests__/__snapshots__/ui.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/__tests__/snapshot.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/__tests__/ui.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/dynamic_settings.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/index_pattern.ts (92%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/index_status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/ml_anomaly.ts (88%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/monitor.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/monitor_duration.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/monitor_list.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/monitor_status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/overview_filters.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/ping.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/ping_list.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/snapshot.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/types.ts (81%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/ui.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/reducers/utils.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/selectors/__tests__/index.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/state/selectors/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/public/uptime_app.tsx (75%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7d1122682be7b4..cee2f32c2cb9e6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -84,7 +84,6 @@ /x-pack/legacy/plugins/ingest_manager/ @elastic/ingest-management /x-pack/plugins/observability/ @elastic/logs-metrics-ui @elastic/apm-ui @elastic/uptime @elastic/ingest-management /x-pack/legacy/plugins/monitoring/ @elastic/stack-monitoring-ui -/x-pack/legacy/plugins/uptime @elastic/uptime /x-pack/plugins/uptime @elastic/uptime # Machine Learning diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index ae1a55254c702a..4acb170d125744 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -43,7 +43,7 @@ "xpack.transform": "plugins/transform", "xpack.triggersActionsUI": "plugins/triggers_actions_ui", "xpack.upgradeAssistant": "plugins/upgrade_assistant", - "xpack.uptime": ["plugins/uptime", "legacy/plugins/uptime"], + "xpack.uptime": ["plugins/uptime"], "xpack.watcher": "plugins/watcher" }, "translations": [ diff --git a/x-pack/index.js b/x-pack/index.js index fe4c3254059337..a4142e24e4aeb6 100644 --- a/x-pack/index.js +++ b/x-pack/index.js @@ -16,7 +16,6 @@ import { spaces } from './legacy/plugins/spaces'; import { canvas } from './legacy/plugins/canvas'; import { infra } from './legacy/plugins/infra'; import { taskManager } from './legacy/plugins/task_manager'; -import { uptime } from './legacy/plugins/uptime'; import { encryptedSavedObjects } from './legacy/plugins/encrypted_saved_objects'; import { actions } from './legacy/plugins/actions'; import { alerting } from './legacy/plugins/alerting'; @@ -37,7 +36,6 @@ module.exports = function(kibana) { canvas(kibana), infra(kibana), taskManager(kibana), - uptime(kibana), encryptedSavedObjects(kibana), actions(kibana), alerting(kibana), diff --git a/x-pack/legacy/plugins/uptime/common/graphql/types.ts b/x-pack/legacy/plugins/uptime/common/graphql/types.ts deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/x-pack/legacy/plugins/uptime/index.ts b/x-pack/legacy/plugins/uptime/index.ts deleted file mode 100644 index f52ad8ce867b61..00000000000000 --- a/x-pack/legacy/plugins/uptime/index.ts +++ /dev/null @@ -1,36 +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 { i18n } from '@kbn/i18n'; -import { resolve } from 'path'; -import { PLUGIN } from './common/constants'; -import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils'; - -export const uptime = (kibana: any) => - new kibana.Plugin({ - configPrefix: 'xpack.uptime', - id: PLUGIN.ID, - publicDir: resolve(__dirname, 'public'), - require: ['alerting', 'kibana', 'elasticsearch', 'xpack_main'], - uiExports: { - app: { - description: i18n.translate('xpack.uptime.pluginDescription', { - defaultMessage: 'Uptime monitoring', - description: 'The description text that will be shown to users in Kibana', - }), - icon: 'plugins/uptime/icons/heartbeat_white.svg', - euiIconType: 'uptimeApp', - title: i18n.translate('xpack.uptime.uptimeFeatureCatalogueTitle', { - defaultMessage: 'Uptime', - }), - main: 'plugins/uptime/app', - order: 8900, - url: '/app/uptime#/', - category: DEFAULT_APP_CATEGORIES.observability, - }, - home: ['plugins/uptime/register_feature'], - }, - }); diff --git a/x-pack/legacy/plugins/uptime/public/apps/index.ts b/x-pack/legacy/plugins/uptime/public/apps/index.ts deleted file mode 100644 index d58bf8398fcdea..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/apps/index.ts +++ /dev/null @@ -1,16 +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 { npSetup } from 'ui/new_platform'; -import { Plugin } from './plugin'; -import 'uiExports/embeddableFactories'; - -const plugin = new Plugin({ - opaqueId: Symbol('uptime'), - env: {} as any, - config: { get: () => ({} as any) }, -}); -plugin.setup(npSetup); diff --git a/x-pack/legacy/plugins/uptime/public/apps/plugin.ts b/x-pack/legacy/plugins/uptime/public/apps/plugin.ts deleted file mode 100644 index e73598c44c9f08..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/apps/plugin.ts +++ /dev/null @@ -1,56 +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 { LegacyCoreSetup, PluginInitializerContext, AppMountParameters } from 'src/core/public'; -import { PluginsSetup } from 'ui/new_platform/new_platform'; -import { FeatureCatalogueCategory } from '../../../../../../src/plugins/home/public'; -import { UMFrontendLibs } from '../lib/lib'; -import { PLUGIN } from '../../common/constants'; -import { getKibanaFrameworkAdapter } from '../lib/adapters/framework/new_platform_adapter'; - -export interface SetupObject { - core: LegacyCoreSetup; - plugins: PluginsSetup; -} - -export class Plugin { - constructor( - // @ts-ignore this is added to satisfy the New Platform typing constraint, - // but we're not leveraging any of its functionality yet. - private readonly initializerContext: PluginInitializerContext - ) {} - - public setup(setup: SetupObject) { - const { core, plugins } = setup; - const { home } = plugins; - - home.featureCatalogue.register({ - category: FeatureCatalogueCategory.DATA, - description: PLUGIN.DESCRIPTION, - icon: 'uptimeApp', - id: PLUGIN.ID, - path: '/app/uptime#/', - showOnHomePage: true, - title: PLUGIN.TITLE, - }); - - core.application.register({ - id: PLUGIN.ID, - euiIconType: 'uptimeApp', - order: 8900, - title: 'Uptime', - async mount(params: AppMountParameters) { - const [coreStart] = await core.getStartServices(); - const { element } = params; - const libs: UMFrontendLibs = { - framework: getKibanaFrameworkAdapter(coreStart, plugins), - }; - libs.framework.render(element); - return () => {}; - }, - }); - } -} diff --git a/x-pack/legacy/plugins/uptime/public/register_feature.ts b/x-pack/legacy/plugins/uptime/public/register_feature.ts deleted file mode 100644 index 2f83fa33ba4bc5..00000000000000 --- a/x-pack/legacy/plugins/uptime/public/register_feature.ts +++ /dev/null @@ -1,25 +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 { i18n } from '@kbn/i18n'; -import { npSetup } from 'ui/new_platform'; -import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public'; - -const { - plugins: { home }, -} = npSetup; - -home.featureCatalogue.register({ - id: 'uptime', - title: i18n.translate('xpack.uptime.uptimeFeatureCatalogueTitle', { defaultMessage: 'Uptime' }), - description: i18n.translate('xpack.uptime.featureCatalogueDescription', { - defaultMessage: 'Perform endpoint health checks and uptime monitoring.', - }), - icon: 'uptimeApp', - path: `uptime#/`, - showOnHomePage: true, - category: FeatureCatalogueCategory.DATA, -}); diff --git a/x-pack/legacy/plugins/uptime/tsconfig.json b/x-pack/legacy/plugins/uptime/tsconfig.json deleted file mode 100644 index 53425909db3e8b..00000000000000 --- a/x-pack/legacy/plugins/uptime/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "exclude": ["**/node_modules/**"], - "paths": { - "react": ["../../../node_modules/@types/react"] - } -} \ No newline at end of file diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index cdff34ec3a6039..fd986ca0851d6f 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -16112,7 +16112,6 @@ "xpack.uptime.emptyStateError.notAuthorized": "アップタイムデータの表示が承認されていません。システム管理者にお問い合わせください。", "xpack.uptime.emptyStateError.notFoundPage": "ページが見つかりません", "xpack.uptime.emptyStateError.title": "エラー", - "xpack.uptime.featureCatalogueDescription": "エンドポイントヘルスチェックとアップタイム監視を行います。", "xpack.uptime.featureRegistry.uptimeFeatureName": "アップタイム", "xpack.uptime.filterBar.ariaLabel": "概要ページのインプットフィルター基準", "xpack.uptime.filterBar.filterDownLabel": "ダウン", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 819112feb9f572..162251f20c5c01 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -16117,7 +16117,6 @@ "xpack.uptime.emptyStateError.notAuthorized": "您无权查看 Uptime 数据,请联系系统管理员。", "xpack.uptime.emptyStateError.notFoundPage": "未找到页面", "xpack.uptime.emptyStateError.title": "错误", - "xpack.uptime.featureCatalogueDescription": "执行终端节点运行状况检查和运行时间监测。", "xpack.uptime.featureRegistry.uptimeFeatureName": "运行时间", "xpack.uptime.filterBar.ariaLabel": "概览页面的输入筛选条件", "xpack.uptime.filterBar.filterDownLabel": "关闭", diff --git a/x-pack/legacy/plugins/uptime/README.md b/x-pack/plugins/uptime/README.md similarity index 100% rename from x-pack/legacy/plugins/uptime/README.md rename to x-pack/plugins/uptime/README.md diff --git a/x-pack/legacy/plugins/uptime/common/constants/alerts.ts b/x-pack/plugins/uptime/common/constants/alerts.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/alerts.ts rename to x-pack/plugins/uptime/common/constants/alerts.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/capabilities.ts b/x-pack/plugins/uptime/common/constants/capabilities.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/capabilities.ts rename to x-pack/plugins/uptime/common/constants/capabilities.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/chart_format_limits.ts b/x-pack/plugins/uptime/common/constants/chart_format_limits.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/chart_format_limits.ts rename to x-pack/plugins/uptime/common/constants/chart_format_limits.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/client_defaults.ts b/x-pack/plugins/uptime/common/constants/client_defaults.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/client_defaults.ts rename to x-pack/plugins/uptime/common/constants/client_defaults.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/context_defaults.ts b/x-pack/plugins/uptime/common/constants/context_defaults.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/context_defaults.ts rename to x-pack/plugins/uptime/common/constants/context_defaults.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/index.ts b/x-pack/plugins/uptime/common/constants/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/index.ts rename to x-pack/plugins/uptime/common/constants/index.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/plugin.ts b/x-pack/plugins/uptime/common/constants/plugin.ts similarity index 64% rename from x-pack/legacy/plugins/uptime/common/constants/plugin.ts rename to x-pack/plugins/uptime/common/constants/plugin.ts index 00781726941d5c..6064524872a0ac 100644 --- a/x-pack/legacy/plugins/uptime/common/constants/plugin.ts +++ b/x-pack/plugins/uptime/common/constants/plugin.ts @@ -8,12 +8,17 @@ import { i18n } from '@kbn/i18n'; export const PLUGIN = { APP_ROOT_ID: 'react-uptime-root', - DESCRIPTION: 'Uptime monitoring', + DESCRIPTION: i18n.translate('xpack.uptime.pluginDescription', { + defaultMessage: 'Uptime monitoring', + description: 'The description text that will appear in the feature catalogue.', + }), ID: 'uptime', LOCAL_STORAGE_KEY: 'xpack.uptime', NAME: i18n.translate('xpack.uptime.featureRegistry.uptimeFeatureName', { defaultMessage: 'Uptime', }), ROUTER_BASE_NAME: '/app/uptime#', - TITLE: 'uptime', + TITLE: i18n.translate('xpack.uptime.uptimeFeatureCatalogueTitle', { + defaultMessage: 'Uptime', + }), }; diff --git a/x-pack/legacy/plugins/uptime/common/constants/query.ts b/x-pack/plugins/uptime/common/constants/query.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/query.ts rename to x-pack/plugins/uptime/common/constants/query.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/rest_api.ts b/x-pack/plugins/uptime/common/constants/rest_api.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/rest_api.ts rename to x-pack/plugins/uptime/common/constants/rest_api.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/settings_defaults.ts b/x-pack/plugins/uptime/common/constants/settings_defaults.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/settings_defaults.ts rename to x-pack/plugins/uptime/common/constants/settings_defaults.ts diff --git a/x-pack/legacy/plugins/uptime/common/constants/ui.ts b/x-pack/plugins/uptime/common/constants/ui.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/constants/ui.ts rename to x-pack/plugins/uptime/common/constants/ui.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/alerts/index.ts b/x-pack/plugins/uptime/common/runtime_types/alerts/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/alerts/index.ts rename to x-pack/plugins/uptime/common/runtime_types/alerts/index.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/alerts/status_check.ts b/x-pack/plugins/uptime/common/runtime_types/alerts/status_check.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/alerts/status_check.ts rename to x-pack/plugins/uptime/common/runtime_types/alerts/status_check.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/certs.ts b/x-pack/plugins/uptime/common/runtime_types/certs.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/certs.ts rename to x-pack/plugins/uptime/common/runtime_types/certs.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/common.ts b/x-pack/plugins/uptime/common/runtime_types/common.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/common.ts rename to x-pack/plugins/uptime/common/runtime_types/common.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts b/x-pack/plugins/uptime/common/runtime_types/dynamic_settings.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/dynamic_settings.ts rename to x-pack/plugins/uptime/common/runtime_types/dynamic_settings.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/index.ts b/x-pack/plugins/uptime/common/runtime_types/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/index.ts rename to x-pack/plugins/uptime/common/runtime_types/index.ts index 78aab3806ae049..e80471bf8b56f9 100644 --- a/x-pack/legacy/plugins/uptime/common/runtime_types/index.ts +++ b/x-pack/plugins/uptime/common/runtime_types/index.ts @@ -7,8 +7,8 @@ export * from './alerts'; export * from './certs'; export * from './common'; +export * from './dynamic_settings'; export * from './monitor'; export * from './overview_filters'; export * from './ping'; export * from './snapshot'; -export * from './dynamic_settings'; diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/monitor/details.ts b/x-pack/plugins/uptime/common/runtime_types/monitor/details.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/monitor/details.ts rename to x-pack/plugins/uptime/common/runtime_types/monitor/details.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/monitor/index.ts b/x-pack/plugins/uptime/common/runtime_types/monitor/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/monitor/index.ts rename to x-pack/plugins/uptime/common/runtime_types/monitor/index.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/monitor/locations.ts b/x-pack/plugins/uptime/common/runtime_types/monitor/locations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/monitor/locations.ts rename to x-pack/plugins/uptime/common/runtime_types/monitor/locations.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/monitor/state.ts b/x-pack/plugins/uptime/common/runtime_types/monitor/state.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/monitor/state.ts rename to x-pack/plugins/uptime/common/runtime_types/monitor/state.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/overview_filters/index.ts b/x-pack/plugins/uptime/common/runtime_types/overview_filters/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/overview_filters/index.ts rename to x-pack/plugins/uptime/common/runtime_types/overview_filters/index.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/overview_filters/overview_filters.ts b/x-pack/plugins/uptime/common/runtime_types/overview_filters/overview_filters.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/overview_filters/overview_filters.ts rename to x-pack/plugins/uptime/common/runtime_types/overview_filters/overview_filters.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/ping/histogram.ts b/x-pack/plugins/uptime/common/runtime_types/ping/histogram.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/ping/histogram.ts rename to x-pack/plugins/uptime/common/runtime_types/ping/histogram.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/ping/index.ts b/x-pack/plugins/uptime/common/runtime_types/ping/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/ping/index.ts rename to x-pack/plugins/uptime/common/runtime_types/ping/index.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/ping/ping.ts b/x-pack/plugins/uptime/common/runtime_types/ping/ping.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/ping/ping.ts rename to x-pack/plugins/uptime/common/runtime_types/ping/ping.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/snapshot/index.ts b/x-pack/plugins/uptime/common/runtime_types/snapshot/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/snapshot/index.ts rename to x-pack/plugins/uptime/common/runtime_types/snapshot/index.ts diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/snapshot/snapshot_count.ts b/x-pack/plugins/uptime/common/runtime_types/snapshot/snapshot_count.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/common/runtime_types/snapshot/snapshot_count.ts rename to x-pack/plugins/uptime/common/runtime_types/snapshot/snapshot_count.ts diff --git a/x-pack/legacy/plugins/uptime/common/types/index.ts b/x-pack/plugins/uptime/common/types/index.ts similarity index 69% rename from x-pack/legacy/plugins/uptime/common/types/index.ts rename to x-pack/plugins/uptime/common/types/index.ts index a32eabd49a3e5e..71ccd54dd3cdcd 100644 --- a/x-pack/legacy/plugins/uptime/common/types/index.ts +++ b/x-pack/plugins/uptime/common/types/index.ts @@ -4,18 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/** Represents a bucket of monitor status information. */ -export interface StatusData { - /** The timeseries point for this status data. */ - x: number; - /** The value of up counts for this point. */ - up?: number | null; - /** The value for down counts for this point. */ - down?: number | null; - /** The total down counts for this point. */ - total?: number | null; -} - /** Represents the average monitor duration ms at a point in time. */ export interface MonitorDurationAveragePoint { /** The timeseries value for this point. */ diff --git a/x-pack/plugins/uptime/kibana.json b/x-pack/plugins/uptime/kibana.json index 6ec8a755ebea09..ce8b64ce07254a 100644 --- a/x-pack/plugins/uptime/kibana.json +++ b/x-pack/plugins/uptime/kibana.json @@ -2,8 +2,16 @@ "configPath": ["xpack", "uptime"], "id": "uptime", "kibanaVersion": "kibana", - "requiredPlugins": ["alerting", "features", "licensing", "usageCollection"], + "optionalPlugins": ["capabilities", "data", "home"], + "requiredPlugins": [ + "alerting", + "embeddable", + "features", + "licensing", + "triggers_actions_ui", + "usageCollection" + ], "server": true, - "ui": false, + "ui": true, "version": "8.0.0" } diff --git a/x-pack/legacy/plugins/uptime/public/app.ts b/x-pack/plugins/uptime/public/app.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/app.ts rename to x-pack/plugins/uptime/public/app.ts diff --git a/x-pack/legacy/plugins/uptime/common/graphql/resolver_types.ts b/x-pack/plugins/uptime/public/apps/index.ts similarity index 56% rename from x-pack/legacy/plugins/uptime/common/graphql/resolver_types.ts rename to x-pack/plugins/uptime/public/apps/index.ts index 22df610d2d516c..65b80d08d4f20f 100644 --- a/x-pack/legacy/plugins/uptime/common/graphql/resolver_types.ts +++ b/x-pack/plugins/uptime/public/apps/index.ts @@ -4,10 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -type UMResolverResult = Promise | T; - -export type UMResolver = ( - parent: Parent, - args: Args, - context: Context -) => UMResolverResult; +export { UptimePlugin } from './plugin'; diff --git a/x-pack/plugins/uptime/public/apps/plugin.ts b/x-pack/plugins/uptime/public/apps/plugin.ts new file mode 100644 index 00000000000000..719dac022dada8 --- /dev/null +++ b/x-pack/plugins/uptime/public/apps/plugin.ts @@ -0,0 +1,72 @@ +/* + * 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 { LegacyCoreStart, AppMountParameters } from 'src/core/public'; +import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/public'; +import { UMFrontendLibs } from '../lib/lib'; +import { PLUGIN } from '../../common/constants'; +import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public'; +import { getKibanaFrameworkAdapter } from '../lib/adapters/framework/new_platform_adapter'; +import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public'; +import { EmbeddableStart } from '../../../../../src/plugins/embeddable/public'; +import { TriggersAndActionsUIPublicPluginSetup } from '../../../triggers_actions_ui/public'; +import { DataPublicPluginSetup } from '../../../../../src/plugins/data/public'; + +export interface StartObject { + core: LegacyCoreStart; + plugins: any; +} + +export interface ClientPluginsSetup { + data: DataPublicPluginSetup; + home: HomePublicPluginSetup; + triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup; +} + +export interface ClientPluginsStart { + embeddable: EmbeddableStart; +} + +export class UptimePlugin implements Plugin { + constructor(_context: PluginInitializerContext) {} + + public async setup( + core: CoreSetup, + plugins: ClientPluginsSetup + ): Promise { + if (plugins.home) { + plugins.home.featureCatalogue.register({ + id: PLUGIN.ID, + title: PLUGIN.TITLE, + description: PLUGIN.DESCRIPTION, + icon: 'uptimeApp', + path: '/app/uptime#/', + showOnHomePage: true, + category: FeatureCatalogueCategory.DATA, + }); + } + + core.application.register({ + appRoute: '/app/uptime#/', + id: PLUGIN.ID, + euiIconType: 'uptimeApp', + order: 8900, + title: PLUGIN.TITLE, + async mount(params: AppMountParameters) { + const [coreStart, corePlugins] = await core.getStartServices(); + const { element } = params; + const libs: UMFrontendLibs = { + framework: getKibanaFrameworkAdapter(coreStart, plugins, corePlugins), + }; + libs.framework.render(element); + return () => {}; + }, + }); + } + + public start(_start: CoreStart, _plugins: {}): void {} + + public stop(): void {} +} diff --git a/x-pack/legacy/plugins/uptime/public/apps/template.html b/x-pack/plugins/uptime/public/apps/template.html similarity index 100% rename from x-pack/legacy/plugins/uptime/public/apps/template.html rename to x-pack/plugins/uptime/public/apps/template.html diff --git a/x-pack/legacy/plugins/uptime/public/badge.ts b/x-pack/plugins/uptime/public/badge.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/badge.ts rename to x-pack/plugins/uptime/public/badge.ts diff --git a/x-pack/legacy/plugins/uptime/public/breadcrumbs.ts b/x-pack/plugins/uptime/public/breadcrumbs.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/breadcrumbs.ts rename to x-pack/plugins/uptime/public/breadcrumbs.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/common/__tests__/__snapshots__/location_link.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/__tests__/__snapshots__/location_link.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/__tests__/__snapshots__/location_link.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/__tests__/__snapshots__/location_link.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/__tests__/__snapshots__/uptime_date_picker.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/__tests__/location_link.test.tsx b/x-pack/plugins/uptime/public/components/common/__tests__/location_link.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/__tests__/location_link.test.tsx rename to x-pack/plugins/uptime/public/components/common/__tests__/location_link.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/__tests__/uptime_date_picker.test.tsx b/x-pack/plugins/uptime/public/components/common/__tests__/uptime_date_picker.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/__tests__/uptime_date_picker.test.tsx rename to x-pack/plugins/uptime/public/components/common/__tests__/uptime_date_picker.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_empty_state.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/donut_chart_legend_row.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/duration_charts.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/monitor_bar_series.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/monitor_bar_series.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/monitor_bar_series.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/monitor_bar_series.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/ping_histogram.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/ping_histogram.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/ping_histogram.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/__snapshots__/ping_histogram.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/chart_empty_state.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/chart_empty_state.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/chart_empty_state.test.tsx rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/chart_empty_state.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/chart_wrapper.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/chart_wrapper.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/chart_wrapper.test.tsx rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/chart_wrapper.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/donut_chart.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/donut_chart.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/donut_chart.test.tsx rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/donut_chart.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend.test.tsx rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend_row.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend_row.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend_row.test.tsx rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/donut_chart_legend_row.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/duration_charts.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/duration_charts.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/duration_charts.test.tsx rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/duration_charts.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/get_tick_format.test.ts b/x-pack/plugins/uptime/public/components/common/charts/__tests__/get_tick_format.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/get_tick_format.test.ts rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/get_tick_format.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/monitor_bar_series.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/monitor_bar_series.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/monitor_bar_series.test.tsx rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/monitor_bar_series.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx rename to x-pack/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/annotation_tooltip.tsx b/x-pack/plugins/uptime/public/components/common/charts/annotation_tooltip.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/annotation_tooltip.tsx rename to x-pack/plugins/uptime/public/components/common/charts/annotation_tooltip.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/chart_empty_state.tsx b/x-pack/plugins/uptime/public/components/common/charts/chart_empty_state.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/chart_empty_state.tsx rename to x-pack/plugins/uptime/public/components/common/charts/chart_empty_state.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/chart_wrapper/chart_wrapper.tsx b/x-pack/plugins/uptime/public/components/common/charts/chart_wrapper/chart_wrapper.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/chart_wrapper/chart_wrapper.tsx rename to x-pack/plugins/uptime/public/components/common/charts/chart_wrapper/chart_wrapper.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/chart_wrapper/index.ts b/x-pack/plugins/uptime/public/components/common/charts/chart_wrapper/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/chart_wrapper/index.ts rename to x-pack/plugins/uptime/public/components/common/charts/chart_wrapper/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart.tsx b/x-pack/plugins/uptime/public/components/common/charts/donut_chart.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart.tsx rename to x-pack/plugins/uptime/public/components/common/charts/donut_chart.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx b/x-pack/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx rename to x-pack/plugins/uptime/public/components/common/charts/donut_chart_legend.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart_legend_row.tsx b/x-pack/plugins/uptime/public/components/common/charts/donut_chart_legend_row.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/donut_chart_legend_row.tsx rename to x-pack/plugins/uptime/public/components/common/charts/donut_chart_legend_row.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_chart.tsx b/x-pack/plugins/uptime/public/components/common/charts/duration_chart.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/duration_chart.tsx rename to x-pack/plugins/uptime/public/components/common/charts/duration_chart.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx b/x-pack/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx similarity index 94% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx rename to x-pack/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx index a31a143b71fd24..ceb1e700f293e2 100644 --- a/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx +++ b/x-pack/plugins/uptime/public/components/common/charts/duration_line_bar_list.tsx @@ -9,11 +9,11 @@ import moment from 'moment'; import { AnnotationTooltipFormatter, RectAnnotation } from '@elastic/charts'; import { RectAnnotationDatum } from '@elastic/charts/dist/chart_types/xy_chart/utils/specs'; import { AnnotationTooltip } from './annotation_tooltip'; -import { ANOMALY_SEVERITY } from '../../../../../../../plugins/ml/common/constants/anomalies'; +import { ANOMALY_SEVERITY } from '../../../../../../plugins/ml/common/constants/anomalies'; import { getSeverityColor, getSeverityType, -} from '../../../../../../../plugins/ml/common/util/anomaly_utils'; +} from '../../../../../../plugins/ml/common/util/anomaly_utils'; interface Props { anomalies: any; diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_series_list.tsx b/x-pack/plugins/uptime/public/components/common/charts/duration_line_series_list.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/duration_line_series_list.tsx rename to x-pack/plugins/uptime/public/components/common/charts/duration_line_series_list.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/get_tick_format.ts b/x-pack/plugins/uptime/public/components/common/charts/get_tick_format.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/get_tick_format.ts rename to x-pack/plugins/uptime/public/components/common/charts/get_tick_format.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/index.ts b/x-pack/plugins/uptime/public/components/common/charts/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/index.ts rename to x-pack/plugins/uptime/public/components/common/charts/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/monitor_bar_series.tsx b/x-pack/plugins/uptime/public/components/common/charts/monitor_bar_series.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/monitor_bar_series.tsx rename to x-pack/plugins/uptime/public/components/common/charts/monitor_bar_series.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/charts/ping_histogram.tsx b/x-pack/plugins/uptime/public/components/common/charts/ping_histogram.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/charts/ping_histogram.tsx rename to x-pack/plugins/uptime/public/components/common/charts/ping_histogram.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap b/x-pack/plugins/uptime/public/components/common/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap rename to x-pack/plugins/uptime/public/components/common/higher_order/__tests__/__snapshots__/responsive_wrapper.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/common/higher_order/__tests__/responsive_wrapper.test.tsx b/x-pack/plugins/uptime/public/components/common/higher_order/__tests__/responsive_wrapper.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/higher_order/__tests__/responsive_wrapper.test.tsx rename to x-pack/plugins/uptime/public/components/common/higher_order/__tests__/responsive_wrapper.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/higher_order/index.ts b/x-pack/plugins/uptime/public/components/common/higher_order/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/higher_order/index.ts rename to x-pack/plugins/uptime/public/components/common/higher_order/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/common/higher_order/responsive_wrapper.tsx b/x-pack/plugins/uptime/public/components/common/higher_order/responsive_wrapper.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/higher_order/responsive_wrapper.tsx rename to x-pack/plugins/uptime/public/components/common/higher_order/responsive_wrapper.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/location_link.tsx b/x-pack/plugins/uptime/public/components/common/location_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/location_link.tsx rename to x-pack/plugins/uptime/public/components/common/location_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/common/uptime_date_picker.tsx b/x-pack/plugins/uptime/public/components/common/uptime_date_picker.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/common/uptime_date_picker.tsx rename to x-pack/plugins/uptime/public/components/common/uptime_date_picker.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/__tests__/__snapshots__/monitor_charts.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/__tests__/__snapshots__/monitor_charts.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/__tests__/__snapshots__/monitor_charts.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/__tests__/__snapshots__/monitor_charts.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/__tests__/monitor_charts.test.tsx b/x-pack/plugins/uptime/public/components/monitor/__tests__/monitor_charts.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/__tests__/monitor_charts.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/__tests__/monitor_charts.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/index.ts b/x-pack/plugins/uptime/public/components/monitor/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/index.ts rename to x-pack/plugins/uptime/public/components/monitor/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_map.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_map.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_map.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_map.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_missing.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/__snapshots__/location_status_tags.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_map.test.tsx b/x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/location_map.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_map.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/location_map.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_missing.test.tsx b/x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/location_missing.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_missing.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/location_missing.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_status_tags.test.tsx b/x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/location_status_tags.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/__tests__/location_status_tags.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/location_map/__tests__/location_status_tags.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/__mocks__/mock.ts b/x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/__mocks__/mock.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/__mocks__/mock.ts rename to x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/__mocks__/mock.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/map_config.test.ts b/x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/map_config.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/map_config.test.ts rename to x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/__tests__/map_config.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx b/x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx similarity index 85% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx rename to x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx index 85d0b1b593704a..06cdb07bd8bcdb 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/embedded_map.tsx @@ -7,21 +7,17 @@ import React, { useEffect, useState, useContext, useRef } from 'react'; import uuid from 'uuid'; import styled from 'styled-components'; -import { npStart } from 'ui/new_platform'; - -import { - ViewMode, - EmbeddableOutput, - ErrorEmbeddable, - isErrorEmbeddable, -} from '../../../../../../../../../src/plugins/embeddable/public'; +import { MapEmbeddable, MapEmbeddableInput } from '../../../../../../../legacy/plugins/maps/public'; import * as i18n from './translations'; -import { MapEmbeddable, MapEmbeddableInput } from '../../../../../../maps/public'; -import { MAP_SAVED_OBJECT_TYPE } from '../../../../../../../../plugins/maps/public'; import { Location } from '../../../../../common/runtime_types'; - import { getLayerList } from './map_config'; -import { UptimeThemeContext } from '../../../../contexts'; +import { UptimeThemeContext, UptimeStartupPluginsContext } from '../../../../contexts'; +import { + isErrorEmbeddable, + ViewMode, + ErrorEmbeddable, +} from '../../../../../../../../src/plugins/embeddable/public'; +import { MAP_SAVED_OBJECT_TYPE } from '../../../../../../maps/public'; export interface EmbeddedMapProps { upPoints: LocationPoint[]; @@ -52,11 +48,11 @@ export const EmbeddedMap = React.memo(({ upPoints, downPoints }: EmbeddedMapProp const { colors } = useContext(UptimeThemeContext); const [embeddable, setEmbeddable] = useState(); const embeddableRoot: React.RefObject = useRef(null); - const factory = npStart.plugins.embeddable.getEmbeddableFactory< - MapEmbeddableInput, - EmbeddableOutput, - MapEmbeddable - >(MAP_SAVED_OBJECT_TYPE); + const { embeddable: embeddablePlugin } = useContext(UptimeStartupPluginsContext); + if (!embeddablePlugin) { + throw new Error('Embeddable start plugin not found'); + } + const factory: any = embeddablePlugin.getEmbeddableFactory(MAP_SAVED_OBJECT_TYPE); const input: MapEmbeddableInput = { id: uuid.v4(), @@ -88,7 +84,7 @@ export const EmbeddedMap = React.memo(({ upPoints, downPoints }: EmbeddedMapProp if (!factory) { throw new Error('Map embeddable not found.'); } - const embeddableObject = await factory.create({ + const embeddableObject: any = await factory.create({ ...input, title: i18n.MAP_TITLE, }); diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/low_poly_layer.json b/x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/low_poly_layer.json similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/low_poly_layer.json rename to x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/low_poly_layer.json diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/map_config.ts b/x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/map_config.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/map_config.ts rename to x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/map_config.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/translations.ts b/x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/translations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/embeddables/translations.ts rename to x-pack/plugins/uptime/public/components/monitor/location_map/embeddables/translations.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/index.tsx b/x-pack/plugins/uptime/public/components/monitor/location_map/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/index.tsx rename to x-pack/plugins/uptime/public/components/monitor/location_map/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_map.tsx b/x-pack/plugins/uptime/public/components/monitor/location_map/location_map.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_map.tsx rename to x-pack/plugins/uptime/public/components/monitor/location_map/location_map.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_missing.tsx b/x-pack/plugins/uptime/public/components/monitor/location_map/location_missing.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_missing.tsx rename to x-pack/plugins/uptime/public/components/monitor/location_map/location_missing.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_status_tags.tsx b/x-pack/plugins/uptime/public/components/monitor/location_map/location_status_tags.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/location_map/location_status_tags.tsx rename to x-pack/plugins/uptime/public/components/monitor/location_map/location_status_tags.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/confirm_delete.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/license_info.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/license_info.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/license_info.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/license_info.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_flyout.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_integerations.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_job_link.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/__snapshots__/ml_manage_job.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/confirm_delete.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/confirm_delete.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/confirm_delete.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/confirm_delete.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/license_info.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/license_info.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/license_info.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/license_info.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx index c0b02181dcce1a..31cdcfac9feef3 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_flyout.test.tsx @@ -9,7 +9,7 @@ import { renderWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; import { MLFlyoutView } from '../ml_flyout'; import { UptimeSettingsContext } from '../../../../contexts'; import { CLIENT_DEFAULTS } from '../../../../../common/constants'; -import { License } from '../../../../../../../../plugins/licensing/common/license'; +import { License } from '../../../../../../../plugins/licensing/common/license'; const expiredLicense = new License({ signature: 'test signature', diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_integerations.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_integerations.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_integerations.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_integerations.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_job_link.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_job_link.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_job_link.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_job_link.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_manage_job.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_manage_job.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/__tests__/ml_manage_job.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/__tests__/ml_manage_job.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/confirm_delete.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/confirm_delete.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/confirm_delete.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/confirm_delete.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/index.ts b/x-pack/plugins/uptime/public/components/monitor/ml/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/index.ts rename to x-pack/plugins/uptime/public/components/monitor/ml/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/license_info.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/license_info.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/license_info.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/license_info.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/manage_ml_job.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx similarity index 98% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx index c3e8579ca48370..6eec30d405f769 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout_container.tsx @@ -19,7 +19,7 @@ import * as labels from './translations'; import { useKibana, KibanaReactNotifications, -} from '../../../../../../../../src/plugins/kibana_react/public'; +} from '../../../../../../../src/plugins/kibana_react/public'; import { MLFlyoutView } from './ml_flyout'; import { ML_JOB_ID } from '../../../../common/constants'; import { UptimeRefreshContext, UptimeSettingsContext } from '../../../contexts'; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx similarity index 95% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx index 4963a901f0ecc5..7f19885c15406e 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ml/ml_integeration.tsx @@ -18,9 +18,9 @@ import { ConfirmJobDeletion } from './confirm_delete'; import { UptimeRefreshContext } from '../../../contexts'; import { getMLJobId } from '../../../state/api/ml_anomaly'; import * as labels from './translations'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; import { ManageMLJobComponent } from './manage_ml_job'; -import { JobStat } from '../../../../../../../plugins/ml/common/types/data_recognizer'; +import { JobStat } from '../../../../../../plugins/ml/common/types/data_recognizer'; import { useMonitorId } from '../../../hooks'; export const MLIntegrationComponent = () => { diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_job_link.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_job_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/ml_job_link.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/ml_job_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ml/translations.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/translations.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ml/translations.tsx rename to x-pack/plugins/uptime/public/components/monitor/ml/translations.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_charts.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_charts.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_charts.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_charts.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/index.ts b/x-pack/plugins/uptime/public/components/monitor/monitor_duration/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/index.ts rename to x-pack/plugins/uptime/public/components/monitor/monitor_duration/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx similarity index 96% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx index 7e39b977f12710..52d4f620f84b3f 100644 --- a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/monitor_duration/monitor_duration_container.tsx @@ -20,7 +20,7 @@ import { } from '../../../state/selectors'; import { UptimeRefreshContext } from '../../../contexts'; import { getMLJobId } from '../../../state/api/ml_anomaly'; -import { JobStat } from '../../../../../../../plugins/ml/common/types/data_recognizer'; +import { JobStat } from '../../../../../ml/common/types/data_recognizer'; import { MonitorDurationComponent } from './monitor_duration'; import { MonitorIdParam } from '../../../../common/types'; diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_ssl_certificate.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_ssl_certificate.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_ssl_certificate.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_ssl_certificate.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_status.bar.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_status.bar.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_status.bar.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/monitor_status.bar.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/status_by_location.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/status_by_location.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/status_by_location.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/__snapshots__/status_by_location.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_ssl_certificate.test.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_ssl_certificate.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_ssl_certificate.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_ssl_certificate.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_status.bar.test.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_status.bar.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_status.bar.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/monitor_status.bar.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/status_by_location.test.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/status_by_location.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/__test__/status_by_location.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/__test__/status_by_location.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/index.ts b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/index.ts rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/index.ts b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/index.ts rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/ssl_certificate.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/ssl_certificate.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/ssl_certificate.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/ssl_certificate.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar_container.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar_container.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_bar_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_by_location.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_by_location.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_by_location.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/status_by_location.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/translations.ts b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/translations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/translations.ts rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/monitor_status_bar/translations.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/status_details.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/status_details.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details_container.tsx b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/status_details_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/status_details_container.tsx rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/status_details_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/translations.ts b/x-pack/plugins/uptime/public/components/monitor/monitor_status_details/translations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/monitor_status_details/translations.ts rename to x-pack/plugins/uptime/public/components/monitor/monitor_status_details/translations.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/index.ts b/x-pack/plugins/uptime/public/components/monitor/ping_histogram/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/index.ts rename to x-pack/plugins/uptime/public/components/monitor/ping_histogram/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/ping_histogram_container.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_histogram/ping_histogram_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_histogram/ping_histogram_container.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_histogram/ping_histogram_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/doc_link_body.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/expanded_row.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap b/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap rename to x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/__snapshots__/ping_list.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/doc_link_body.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/doc_link_body.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/doc_link_body.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/doc_link_body.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/expanded_row.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/expanded_row.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/expanded_row.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/expanded_row.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/ping_list.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/ping_list.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/__tests__/ping_list.test.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/__tests__/ping_list.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/doc_link_body.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/doc_link_body.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/doc_link_body.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/doc_link_body.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/expanded_row.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/expanded_row.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/expanded_row.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/expanded_row.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/index.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/index.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/index.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/index.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/location_name.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/location_name.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/location_name.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/location_name.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/ping_list.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list_container.tsx b/x-pack/plugins/uptime/public/components/monitor/ping_list/ping_list_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/monitor/ping_list/ping_list_container.tsx rename to x-pack/plugins/uptime/public/components/monitor/ping_list/ping_list_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/parsing_error_callout.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/parsing_error_callout.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/parsing_error_callout.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/parsing_error_callout.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot_heading.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot_heading.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot_heading.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/__tests__/__snapshots__/snapshot_heading.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/parsing_error_callout.test.tsx b/x-pack/plugins/uptime/public/components/overview/__tests__/parsing_error_callout.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/__tests__/parsing_error_callout.test.tsx rename to x-pack/plugins/uptime/public/components/overview/__tests__/parsing_error_callout.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot.test.tsx b/x-pack/plugins/uptime/public/components/overview/__tests__/snapshot.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot.test.tsx rename to x-pack/plugins/uptime/public/components/overview/__tests__/snapshot.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot_heading.test.tsx b/x-pack/plugins/uptime/public/components/overview/__tests__/snapshot_heading.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/__tests__/snapshot_heading.test.tsx rename to x-pack/plugins/uptime/public/components/overview/__tests__/snapshot_heading.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/__tests__/alert_monitor_status.test.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/__tests__/alert_monitor_status.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/__tests__/alert_monitor_status.test.tsx rename to x-pack/plugins/uptime/public/components/overview/alerts/__tests__/alert_monitor_status.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alert_monitor_status.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alert_monitor_status.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/alert_monitor_status.tsx rename to x-pack/plugins/uptime/public/components/overview/alerts/alert_monitor_status.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx rename to x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/alert_monitor_status.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/index.ts b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/index.ts rename to x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx rename to x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/toggle_alert_flyout_button.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx rename to x-pack/plugins/uptime/public/components/overview/alerts/alerts_containers/uptime_alerts_flyout_wrapper.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/index.ts b/x-pack/plugins/uptime/public/components/overview/alerts/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/index.ts rename to x-pack/plugins/uptime/public/components/overview/alerts/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx rename to x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx index 04dfe4b3e3509a..92fc015a276d3f 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/toggle_alert_flyout_button.tsx @@ -8,7 +8,7 @@ import { EuiButtonEmpty, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } f import React, { useState } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; interface Props { setAlertFlyoutVisible: (value: boolean) => void; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx similarity index 83% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx rename to x-pack/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx index 09e6dc72b7f981..262e1552e3660d 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/uptime_alerts_context_provider.tsx @@ -5,8 +5,8 @@ */ import React from 'react'; -import { AlertsContextProvider } from '../../../../../../../plugins/triggers_actions_ui/public'; -import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; +import { AlertsContextProvider } from '../../../../../../plugins/triggers_actions_ui/public'; +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; export const UptimeAlertsContextProvider: React.FC = ({ children }) => { const { diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx b/x-pack/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx similarity index 90% rename from x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx rename to x-pack/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx index 13705e7d192933..9b1d3a73dc6614 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx +++ b/x-pack/plugins/uptime/public/components/overview/alerts/uptime_alerts_flyout_wrapper.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { AlertAdd } from '../../../../../../../plugins/triggers_actions_ui/public'; +import { AlertAdd } from '../../../../../../plugins/triggers_actions_ui/public'; interface Props { alertFlyoutVisible: boolean; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/data_or_index_missing.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/data_or_index_missing.test.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/data_or_index_missing.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/data_or_index_missing.test.tsx rename to x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/data_or_index_missing.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx rename to x-pack/plugins/uptime/public/components/overview/empty_state/__tests__/empty_state.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/data_or_index_missing.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/data_or_index_missing.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/data_or_index_missing.tsx rename to x-pack/plugins/uptime/public/components/overview/empty_state/data_or_index_missing.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.tsx similarity index 96% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state.tsx rename to x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.tsx index 651103a34bf212..d38f203739ceac 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state.tsx +++ b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state.tsx @@ -10,7 +10,7 @@ import { EmptyStateError } from './empty_state_error'; import { EmptyStateLoading } from './empty_state_loading'; import { DataOrIndexMissing } from './data_or_index_missing'; import { DynamicSettings, StatesIndexStatus } from '../../../../common/runtime_types'; -import { IHttpFetchError } from '../../../../../../../../target/types/core/public/http'; +import { IHttpFetchError } from '../../../../../../../target/types/core/public/http'; interface EmptyStateProps { children: JSX.Element[] | JSX.Element; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx rename to x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx similarity index 95% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx rename to x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx index 1135b969018a11..aa4040e319e0f2 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx +++ b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_error.tsx @@ -7,7 +7,7 @@ import { EuiEmptyPrompt, EuiPanel, EuiTitle, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { Fragment } from 'react'; -import { IHttpFetchError } from '../../../../../../../../target/types/core/public/http'; +import { IHttpFetchError } from '../../../../../../../target/types/core/public/http'; interface EmptyStateErrorProps { errors: IHttpFetchError[]; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_loading.tsx b/x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_loading.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/empty_state_loading.tsx rename to x-pack/plugins/uptime/public/components/overview/empty_state/empty_state_loading.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/empty_state/index.ts b/x-pack/plugins/uptime/public/components/overview/empty_state/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/empty_state/index.ts rename to x-pack/plugins/uptime/public/components/overview/empty_state/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_popover.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/filter_status_button.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap b/x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap rename to x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/__snapshots__/parse_filter_map.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_popover.test.tsx b/x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/filter_popover.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_popover.test.tsx rename to x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/filter_popover.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_status_button.test.tsx b/x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/filter_status_button.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/filter_status_button.test.tsx rename to x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/filter_status_button.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/parse_filter_map.test.ts b/x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/parse_filter_map.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/parse_filter_map.test.ts rename to x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/parse_filter_map.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/toggle_selected_item.test.ts b/x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/toggle_selected_item.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/__tests__/toggle_selected_item.test.ts rename to x-pack/plugins/uptime/public/components/overview/filter_group/__tests__/toggle_selected_item.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group.tsx b/x-pack/plugins/uptime/public/components/overview/filter_group/filter_group.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group.tsx rename to x-pack/plugins/uptime/public/components/overview/filter_group/filter_group.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group_container.tsx b/x-pack/plugins/uptime/public/components/overview/filter_group/filter_group_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_group_container.tsx rename to x-pack/plugins/uptime/public/components/overview/filter_group/filter_group_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_popover.tsx b/x-pack/plugins/uptime/public/components/overview/filter_group/filter_popover.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_popover.tsx rename to x-pack/plugins/uptime/public/components/overview/filter_group/filter_popover.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_status_button.tsx b/x-pack/plugins/uptime/public/components/overview/filter_group/filter_status_button.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/filter_status_button.tsx rename to x-pack/plugins/uptime/public/components/overview/filter_group/filter_status_button.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/index.ts b/x-pack/plugins/uptime/public/components/overview/filter_group/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/index.ts rename to x-pack/plugins/uptime/public/components/overview/filter_group/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts b/x-pack/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts rename to x-pack/plugins/uptime/public/components/overview/filter_group/parse_filter_map.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/toggle_selected_item.ts b/x-pack/plugins/uptime/public/components/overview/filter_group/toggle_selected_item.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/toggle_selected_item.ts rename to x-pack/plugins/uptime/public/components/overview/filter_group/toggle_selected_item.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/filter_group/uptime_filter_button.tsx b/x-pack/plugins/uptime/public/components/overview/filter_group/uptime_filter_button.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/filter_group/uptime_filter_button.tsx rename to x-pack/plugins/uptime/public/components/overview/filter_group/uptime_filter_button.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/index.ts b/x-pack/plugins/uptime/public/components/overview/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/index.ts rename to x-pack/plugins/uptime/public/components/overview/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/index.ts b/x-pack/plugins/uptime/public/components/overview/kuery_bar/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/index.ts rename to x-pack/plugins/uptime/public/components/overview/kuery_bar/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx b/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx similarity index 98% rename from x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx rename to x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx index 63aceed2be6362..792fff4c7cdca2 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx +++ b/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar.tsx @@ -16,7 +16,7 @@ import { IIndexPattern, QuerySuggestion, DataPublicPluginSetup, -} from '../../../../../../../../src/plugins/data/public'; +} from '../../../../../../../src/plugins/data/public'; const Container = styled.div` margin-bottom: 10px; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar_container.tsx b/x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/kuery_bar_container.tsx rename to x-pack/plugins/uptime/public/components/overview/kuery_bar/kuery_bar_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/click_outside.js b/x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/click_outside.js similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/click_outside.js rename to x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/click_outside.js diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.d.ts b/x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.d.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.d.ts rename to x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.d.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.js b/x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.js similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.js rename to x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/index.js diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js b/x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js similarity index 97% rename from x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js rename to x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js index 2b5ad9b59e39f8..936eae04ffa641 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js +++ b/x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestion.js @@ -14,7 +14,7 @@ import { units, fontSizes, unit, -} from '../../../../../../apm/public/style/variables'; +} from '../../../../../../../legacy/plugins/apm/public/style/variables'; import { tint } from 'polished'; import theme from '@elastic/eui/dist/eui_theme_light.json'; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js b/x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js similarity index 95% rename from x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js rename to x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js index 7fbabe71bcdb52..ac6832050b9d3c 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js +++ b/x-pack/plugins/uptime/public/components/overview/kuery_bar/typeahead/suggestions.js @@ -9,7 +9,7 @@ import PropTypes from 'prop-types'; import styled from 'styled-components'; import { isEmpty } from 'lodash'; import Suggestion from './suggestion'; -import { units, px, unit } from '../../../../../../apm/public/style/variables'; +import { units, px, unit } from '../../../../../../../legacy/plugins/apm/public/style/variables'; import { tint } from 'polished'; import theme from '@elastic/eui/dist/eui_theme_light.json'; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_list_status_column.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/__snapshots__/monitor_page_link.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_page_size_select.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_page_size_select.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_page_size_select.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_page_size_select.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_status_column.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_status_column.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_status_column.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list_status_column.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_page_link.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_page_link.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_page_link.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_page_link.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/parse_timestamp.test.ts b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/parse_timestamp.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/__tests__/parse_timestamp.test.ts rename to x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/parse_timestamp.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/index.ts b/x-pack/plugins/uptime/public/components/overview/monitor_list/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/index.ts rename to x-pack/plugins/uptime/public/components/overview/monitor_list/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx similarity index 96% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx index 18e2e2437e1477..7e9536689470e6 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list.tsx @@ -202,13 +202,7 @@ export const MonitorListComponent: React.FC = ({ itemId="monitor_id" itemIdToExpandedRowMap={getExpandedRowMap()} items={items} - // TODO: not needed without sorting and pagination - // onChange={onChange} noItemsMessage={!!filters ? labels.NO_MONITOR_ITEM_SELECTED : labels.NO_DATA_MESSAGE} - // TODO: reintegrate pagination in future release - // pagination={pagination} - // TODO: reintegrate sorting in future release - // sorting={sorting} columns={columns} /> diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx similarity index 95% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx index 5bfe6ff0c5b4f1..6fb880e28c7347 100644 --- a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_container.tsx @@ -9,7 +9,7 @@ import { useSelector, useDispatch } from 'react-redux'; import { getMonitorList } from '../../../state/actions'; import { FetchMonitorStatesQueryArgs } from '../../../../common/runtime_types'; import { monitorListSelector } from '../../../state/selectors'; -import { MonitorListComponent } from './index'; +import { MonitorListComponent } from './monitor_list'; export interface MonitorListProps { filters?: string; diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_group.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/integration_link.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_list_drawer.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_list.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/monitor_status_row.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/__snapshots__/most_recent_error.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/data.json b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/data.json similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/data.json rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/data.json diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_link.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_list_drawer.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_list.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/monitor_status_row.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/most_recent_error.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover_container.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover_container.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/actions_popover_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_link.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_link.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/index.ts b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/index.ts rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/list_drawer_container.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/list_drawer_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/list_drawer_container.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/list_drawer_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_list_drawer.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_row.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_row.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_row.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_row.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/most_recent_error.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_page_size_select.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_page_size_select.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_page_size_select.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_page_size_select.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_page_link.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_page_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/monitor_page_link.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_page_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/overview_page_link.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/overview_page_link.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/overview_page_link.tsx rename to x-pack/plugins/uptime/public/components/overview/monitor_list/overview_page_link.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/parse_timestamp.ts b/x-pack/plugins/uptime/public/components/overview/monitor_list/parse_timestamp.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/parse_timestamp.ts rename to x-pack/plugins/uptime/public/components/overview/monitor_list/parse_timestamp.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/translations.ts b/x-pack/plugins/uptime/public/components/overview/monitor_list/translations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/translations.ts rename to x-pack/plugins/uptime/public/components/overview/monitor_list/translations.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/types.ts b/x-pack/plugins/uptime/public/components/overview/monitor_list/types.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/monitor_list/types.ts rename to x-pack/plugins/uptime/public/components/overview/monitor_list/types.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/overview_container.tsx b/x-pack/plugins/uptime/public/components/overview/overview_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/overview_container.tsx rename to x-pack/plugins/uptime/public/components/overview/overview_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/parsing_error_callout.tsx b/x-pack/plugins/uptime/public/components/overview/parsing_error_callout.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/parsing_error_callout.tsx rename to x-pack/plugins/uptime/public/components/overview/parsing_error_callout.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/snapshot/index.ts b/x-pack/plugins/uptime/public/components/overview/snapshot/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/snapshot/index.ts rename to x-pack/plugins/uptime/public/components/overview/snapshot/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/snapshot/snapshot.tsx b/x-pack/plugins/uptime/public/components/overview/snapshot/snapshot.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/snapshot/snapshot.tsx rename to x-pack/plugins/uptime/public/components/overview/snapshot/snapshot.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/snapshot/snapshot_container.tsx b/x-pack/plugins/uptime/public/components/overview/snapshot/snapshot_container.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/snapshot/snapshot_container.tsx rename to x-pack/plugins/uptime/public/components/overview/snapshot/snapshot_container.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/snapshot/snapshot_heading.tsx b/x-pack/plugins/uptime/public/components/overview/snapshot/snapshot_heading.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/snapshot/snapshot_heading.tsx rename to x-pack/plugins/uptime/public/components/overview/snapshot/snapshot_heading.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/overview/status_panel.tsx b/x-pack/plugins/uptime/public/components/overview/status_panel.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/overview/status_panel.tsx rename to x-pack/plugins/uptime/public/components/overview/status_panel.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap b/x-pack/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap rename to x-pack/plugins/uptime/public/components/settings/__tests__/__snapshots__/certificate_form.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap b/x-pack/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap rename to x-pack/plugins/uptime/public/components/settings/__tests__/__snapshots__/indices_form.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx b/x-pack/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx rename to x-pack/plugins/uptime/public/components/settings/__tests__/certificate_form.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx b/x-pack/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx rename to x-pack/plugins/uptime/public/components/settings/__tests__/indices_form.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx b/x-pack/plugins/uptime/public/components/settings/certificate_form.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/settings/certificate_form.tsx rename to x-pack/plugins/uptime/public/components/settings/certificate_form.tsx diff --git a/x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx b/x-pack/plugins/uptime/public/components/settings/indices_form.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/components/settings/indices_form.tsx rename to x-pack/plugins/uptime/public/components/settings/indices_form.tsx diff --git a/x-pack/legacy/plugins/uptime/public/contexts/index.ts b/x-pack/plugins/uptime/public/contexts/index.ts similarity index 82% rename from x-pack/legacy/plugins/uptime/public/contexts/index.ts rename to x-pack/plugins/uptime/public/contexts/index.ts index 2b27fcfe907abd..243a25c26901a1 100644 --- a/x-pack/legacy/plugins/uptime/public/contexts/index.ts +++ b/x-pack/plugins/uptime/public/contexts/index.ts @@ -11,3 +11,7 @@ export { UptimeSettingsContextProvider, } from './uptime_settings_context'; export { UptimeThemeContextProvider, UptimeThemeContext } from './uptime_theme_context'; +export { + UptimeStartupPluginsContext, + UptimeStartupPluginsContextProvider, +} from './uptime_startup_plugins_context'; diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_refresh_context.tsx b/x-pack/plugins/uptime/public/contexts/uptime_refresh_context.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/contexts/uptime_refresh_context.tsx rename to x-pack/plugins/uptime/public/contexts/uptime_refresh_context.tsx diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx b/x-pack/plugins/uptime/public/contexts/uptime_settings_context.tsx similarity index 96% rename from x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx rename to x-pack/plugins/uptime/public/contexts/uptime_settings_context.tsx index 137846de103b4d..4fabf3f2ed4972 100644 --- a/x-pack/legacy/plugins/uptime/public/contexts/uptime_settings_context.tsx +++ b/x-pack/plugins/uptime/public/contexts/uptime_settings_context.tsx @@ -9,7 +9,7 @@ import { UptimeAppProps } from '../uptime_app'; import { CLIENT_DEFAULTS, CONTEXT_DEFAULTS } from '../../common/constants'; import { CommonlyUsedRange } from '../components/common/uptime_date_picker'; import { useGetUrlParams } from '../hooks'; -import { ILicense } from '../../../../../plugins/licensing/common/types'; +import { ILicense } from '../../../../plugins/licensing/common/types'; export interface UptimeSettingsContextValues { basePath: string; diff --git a/x-pack/plugins/uptime/public/contexts/uptime_startup_plugins_context.tsx b/x-pack/plugins/uptime/public/contexts/uptime_startup_plugins_context.tsx new file mode 100644 index 00000000000000..e516ff44aa12ab --- /dev/null +++ b/x-pack/plugins/uptime/public/contexts/uptime_startup_plugins_context.tsx @@ -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. + */ + +import React, { createContext } from 'react'; +import { ClientPluginsStart } from '../apps/plugin'; + +export const UptimeStartupPluginsContext = createContext>({}); + +export const UptimeStartupPluginsContextProvider: React.FC> = ({ + children, + ...props +}) => ; diff --git a/x-pack/legacy/plugins/uptime/public/contexts/uptime_theme_context.tsx b/x-pack/plugins/uptime/public/contexts/uptime_theme_context.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/contexts/uptime_theme_context.tsx rename to x-pack/plugins/uptime/public/contexts/uptime_theme_context.tsx diff --git a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap b/x-pack/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap rename to x-pack/plugins/uptime/public/hooks/__tests__/__snapshots__/use_url_params.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx b/x-pack/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx similarity index 95% rename from x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx rename to x-pack/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx index 1ce00fe7ce3af5..306919015fcb1d 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx +++ b/x-pack/plugins/uptime/public/hooks/__tests__/use_breadcrumbs.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { Route } from 'react-router-dom'; import { mountWithRouter } from '../../lib'; import { OVERVIEW_ROUTE } from '../../../common/constants'; -import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public'; +import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; import { UptimeUrlParams, getSupportedUrlParams } from '../../lib/helper'; import { makeBaseBreadcrumb, useBreadcrumbs } from '../use_breadcrumbs'; diff --git a/x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx b/x-pack/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx rename to x-pack/plugins/uptime/public/hooks/__tests__/use_url_params.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/hooks/index.ts b/x-pack/plugins/uptime/public/hooks/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/hooks/index.ts rename to x-pack/plugins/uptime/public/hooks/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/hooks/update_kuery_string.ts b/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts similarity index 95% rename from x-pack/legacy/plugins/uptime/public/hooks/update_kuery_string.ts rename to x-pack/plugins/uptime/public/hooks/update_kuery_string.ts index ab4d6f75849e88..492d2bab5bb806 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/update_kuery_string.ts +++ b/x-pack/plugins/uptime/public/hooks/update_kuery_string.ts @@ -5,7 +5,7 @@ */ import { combineFiltersAndUserSearch, stringifyKueries } from '../lib/helper'; -import { esKuery, IIndexPattern } from '../../../../../../src/plugins/data/public'; +import { esKuery, IIndexPattern } from '../../../../../src/plugins/data/public'; const getKueryString = (urlFilters: string): string => { let kueryString = ''; diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_breadcrumbs.ts b/x-pack/plugins/uptime/public/hooks/use_breadcrumbs.ts similarity index 94% rename from x-pack/legacy/plugins/uptime/public/hooks/use_breadcrumbs.ts rename to x-pack/plugins/uptime/public/hooks/use_breadcrumbs.ts index d1cc8e18973868..182c6b01141284 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/use_breadcrumbs.ts +++ b/x-pack/plugins/uptime/public/hooks/use_breadcrumbs.ts @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import { useEffect } from 'react'; import { UptimeUrlParams } from '../lib/helper'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; -import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; +import { useKibana } from '../../../../../src/plugins/kibana_react/public'; import { useUrlParams } from '.'; export const makeBaseBreadcrumb = (params?: UptimeUrlParams): ChromeBreadcrumb => { diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_monitor.ts b/x-pack/plugins/uptime/public/hooks/use_monitor.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/hooks/use_monitor.ts rename to x-pack/plugins/uptime/public/hooks/use_monitor.ts diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts b/x-pack/plugins/uptime/public/hooks/use_telemetry.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts rename to x-pack/plugins/uptime/public/hooks/use_telemetry.ts diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts b/x-pack/plugins/uptime/public/hooks/use_url_params.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/hooks/use_url_params.ts rename to x-pack/plugins/uptime/public/hooks/use_url_params.ts diff --git a/x-pack/legacy/plugins/uptime/public/icons/heartbeat_white.svg b/x-pack/plugins/uptime/public/icons/heartbeat_white.svg similarity index 100% rename from x-pack/legacy/plugins/uptime/public/icons/heartbeat_white.svg rename to x-pack/plugins/uptime/public/icons/heartbeat_white.svg diff --git a/x-pack/plugins/uptime/public/index.ts b/x-pack/plugins/uptime/public/index.ts new file mode 100644 index 00000000000000..48cf2c90ad07b1 --- /dev/null +++ b/x-pack/plugins/uptime/public/index.ts @@ -0,0 +1,11 @@ +/* + * 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 { PluginInitializerContext } from 'kibana/public'; +import { UptimePlugin } from './apps'; + +export const plugin = (initializerContext: PluginInitializerContext) => + new UptimePlugin(initializerContext); diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/framework/capabilities_adapter.ts b/x-pack/plugins/uptime/public/lib/adapters/framework/capabilities_adapter.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/adapters/framework/capabilities_adapter.ts rename to x-pack/plugins/uptime/public/lib/adapters/framework/capabilities_adapter.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx b/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx similarity index 86% rename from x-pack/legacy/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx rename to x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx index 71c73bf5ba5d4f..f7f9e056f41af5 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx +++ b/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx @@ -9,7 +9,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { get } from 'lodash'; import { i18n as i18nFormatter } from '@kbn/i18n'; -import { PluginsSetup } from 'ui/new_platform/new_platform'; import { alertTypeInitializers } from '../../alert_types'; import { UptimeApp, UptimeAppProps } from '../../../uptime_app'; import { getIntegratedAppAvailability } from './capabilities_adapter'; @@ -20,10 +19,12 @@ import { DEFAULT_TIMEPICKER_QUICK_RANGES, } from '../../../../common/constants'; import { UMFrameworkAdapter } from '../../lib'; +import { ClientPluginsStart, ClientPluginsSetup } from '../../../apps/plugin'; export const getKibanaFrameworkAdapter = ( core: CoreStart, - plugins: PluginsSetup + plugins: ClientPluginsSetup, + startPlugins: ClientPluginsStart ): UMFrameworkAdapter => { const { application: { capabilities }, @@ -35,14 +36,15 @@ export const getKibanaFrameworkAdapter = ( const { data: { autocomplete }, - // TODO: after NP migration we can likely fix this typing problem - // @ts-ignore we don't control this type triggers_actions_ui, } = plugins; - alertTypeInitializers.forEach(init => - triggers_actions_ui.alertTypeRegistry.register(init({ autocomplete })) - ); + alertTypeInitializers.forEach(init => { + const alertInitializer = init({ autocomplete }); + if (!triggers_actions_ui.alertTypeRegistry.has(alertInitializer.id)) { + triggers_actions_ui.alertTypeRegistry.register(init({ autocomplete })); + } + }); let breadcrumbs: ChromeBreadcrumb[] = []; core.chrome.getBreadcrumbs$().subscribe((nextBreadcrumbs?: ChromeBreadcrumb[]) => { @@ -68,6 +70,7 @@ export const getKibanaFrameworkAdapter = ( isLogsAvailable: logs, kibanaBreadcrumbs: breadcrumbs, plugins, + startPlugins, renderGlobalHelpControls: () => setHelpExtension({ appName: i18nFormatter.translate('xpack.uptime.header.appName', { diff --git a/x-pack/legacy/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts b/x-pack/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts rename to x-pack/plugins/uptime/public/lib/alert_types/__tests__/monitor_status.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/alert_types/index.ts b/x-pack/plugins/uptime/public/lib/alert_types/index.ts similarity index 67% rename from x-pack/legacy/plugins/uptime/public/lib/alert_types/index.ts rename to x-pack/plugins/uptime/public/lib/alert_types/index.ts index 74160577cb0b13..f7ab254ffe675f 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/alert_types/index.ts +++ b/x-pack/plugins/uptime/public/lib/alert_types/index.ts @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -// TODO: after NP migration is complete we should be able to remove this lint ignore comment -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { AlertTypeModel } from '../../../../../../plugins/triggers_actions_ui/public'; +import { AlertTypeModel } from '../../../../triggers_actions_ui/public'; import { initMonitorStatusAlertType } from './monitor_status'; export type AlertTypeInitializer = (dependenies: { autocomplete: any }) => AlertTypeModel; diff --git a/x-pack/legacy/plugins/uptime/public/lib/alert_types/monitor_status.tsx b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx similarity index 88% rename from x-pack/legacy/plugins/uptime/public/lib/alert_types/monitor_status.tsx rename to x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx index 0624d20b197c0e..e7695fb1cbb56c 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/alert_types/monitor_status.tsx +++ b/x-pack/plugins/uptime/public/lib/alert_types/monitor_status.tsx @@ -8,17 +8,12 @@ import { PathReporter } from 'io-ts/lib/PathReporter'; import React from 'react'; import DateMath from '@elastic/datemath'; import { isRight } from 'fp-ts/lib/Either'; -import { - AlertTypeModel, - ValidationResult, - // TODO: this typing issue should be resolved after NP migration - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../plugins/triggers_actions_ui/public/types'; +import { AlertTypeModel } from '../../../../triggers_actions_ui/public'; import { AlertTypeInitializer } from '.'; import { StatusCheckExecutorParamsType } from '../../../common/runtime_types'; import { AlertMonitorStatus } from '../../components/overview/alerts/alerts_containers'; -export const validate = (alertParams: any): ValidationResult => { +export const validate = (alertParams: any) => { const errors: Record = {}; const decoded = StatusCheckExecutorParamsType.decode(alertParams); diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_kueries.test.ts.snap b/x-pack/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_kueries.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_kueries.test.ts.snap rename to x-pack/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_kueries.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_url_params.test.ts.snap b/x-pack/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_url_params.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_url_params.test.ts.snap rename to x-pack/plugins/uptime/public/lib/helper/__tests__/__snapshots__/stringify_url_params.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/combine_filters_and_user_search.test.ts b/x-pack/plugins/uptime/public/lib/helper/__tests__/combine_filters_and_user_search.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/combine_filters_and_user_search.test.ts rename to x-pack/plugins/uptime/public/lib/helper/__tests__/combine_filters_and_user_search.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/convert_measurements.test.ts b/x-pack/plugins/uptime/public/lib/helper/__tests__/convert_measurements.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/convert_measurements.test.ts rename to x-pack/plugins/uptime/public/lib/helper/__tests__/convert_measurements.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts b/x-pack/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts rename to x-pack/plugins/uptime/public/lib/helper/__tests__/series_has_down_values.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/stringify_kueries.test.ts b/x-pack/plugins/uptime/public/lib/helper/__tests__/stringify_kueries.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/stringify_kueries.test.ts rename to x-pack/plugins/uptime/public/lib/helper/__tests__/stringify_kueries.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/stringify_url_params.test.ts b/x-pack/plugins/uptime/public/lib/helper/__tests__/stringify_url_params.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/__tests__/stringify_url_params.test.ts rename to x-pack/plugins/uptime/public/lib/helper/__tests__/stringify_url_params.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/__tests__/get_label_format.test.ts b/x-pack/plugins/uptime/public/lib/helper/charts/__tests__/get_label_format.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/charts/__tests__/get_label_format.test.ts rename to x-pack/plugins/uptime/public/lib/helper/charts/__tests__/get_label_format.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/__tests__/is_within_current_date.test.ts b/x-pack/plugins/uptime/public/lib/helper/charts/__tests__/is_within_current_date.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/charts/__tests__/is_within_current_date.test.ts rename to x-pack/plugins/uptime/public/lib/helper/charts/__tests__/is_within_current_date.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts b/x-pack/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts rename to x-pack/plugins/uptime/public/lib/helper/charts/get_chart_date_label.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts b/x-pack/plugins/uptime/public/lib/helper/charts/get_label_format.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/charts/get_label_format.ts rename to x-pack/plugins/uptime/public/lib/helper/charts/get_label_format.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/index.ts b/x-pack/plugins/uptime/public/lib/helper/charts/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/charts/index.ts rename to x-pack/plugins/uptime/public/lib/helper/charts/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/charts/is_within_current_date.ts b/x-pack/plugins/uptime/public/lib/helper/charts/is_within_current_date.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/charts/is_within_current_date.ts rename to x-pack/plugins/uptime/public/lib/helper/charts/is_within_current_date.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/combine_filters_and_user_search.ts b/x-pack/plugins/uptime/public/lib/helper/combine_filters_and_user_search.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/combine_filters_and_user_search.ts rename to x-pack/plugins/uptime/public/lib/helper/combine_filters_and_user_search.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/convert_measurements.ts b/x-pack/plugins/uptime/public/lib/helper/convert_measurements.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/convert_measurements.ts rename to x-pack/plugins/uptime/public/lib/helper/convert_measurements.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/get_title.ts b/x-pack/plugins/uptime/public/lib/helper/get_title.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/get_title.ts rename to x-pack/plugins/uptime/public/lib/helper/get_title.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/helper_with_router.tsx b/x-pack/plugins/uptime/public/lib/helper/helper_with_router.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/helper_with_router.tsx rename to x-pack/plugins/uptime/public/lib/helper/helper_with_router.tsx diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/index.ts b/x-pack/plugins/uptime/public/lib/helper/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/index.ts rename to x-pack/plugins/uptime/public/lib/helper/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_apm_href.test.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_apm_href.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_apm_href.test.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_apm_href.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_infra_href.test.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_infra_href.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_infra_href.test.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_infra_href.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_logging_href.test.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_logging_href.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_logging_href.test.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/__tests__/get_logging_href.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/add_base_path.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/add_base_path.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/add_base_path.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/add_base_path.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/build_href.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/build_href.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/build_href.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/build_href.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/get_infra_href.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_infra_href.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/get_infra_href.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/get_infra_href.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/get_logging_href.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_logging_href.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/get_logging_href.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/get_logging_href.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/index.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/observability_integration/index.ts rename to x-pack/plugins/uptime/public/lib/helper/observability_integration/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/series_has_down_values.ts b/x-pack/plugins/uptime/public/lib/helper/series_has_down_values.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/series_has_down_values.ts rename to x-pack/plugins/uptime/public/lib/helper/series_has_down_values.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/stringify_kueries.ts b/x-pack/plugins/uptime/public/lib/helper/stringify_kueries.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/stringify_kueries.ts rename to x-pack/plugins/uptime/public/lib/helper/stringify_kueries.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/stringify_url_params.ts b/x-pack/plugins/uptime/public/lib/helper/stringify_url_params.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/stringify_url_params.ts rename to x-pack/plugins/uptime/public/lib/helper/stringify_url_params.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/__snapshots__/get_supported_url_params.test.ts.snap b/x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/__snapshots__/get_supported_url_params.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/__snapshots__/get_supported_url_params.test.ts.snap rename to x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/__snapshots__/get_supported_url_params.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/get_supported_url_params.test.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/get_supported_url_params.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/get_supported_url_params.test.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/get_supported_url_params.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_absolute_date.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_url_int.test.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_autorefresh_interval.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_url_int.test.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_autorefresh_interval.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_is_paused.test.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_is_paused.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/__tests__/parse_is_paused.test.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_is_paused.test.ts diff --git a/x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_url_int.test.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_url_int.test.ts new file mode 100644 index 00000000000000..a5c2168378089d --- /dev/null +++ b/x-pack/plugins/uptime/public/lib/helper/url_params/__tests__/parse_url_int.test.ts @@ -0,0 +1,24 @@ +/* + * 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 { parseUrlInt } from '../parse_url_int'; + +describe('parseUrlInt', () => { + it('parses a number', () => { + const result = parseUrlInt('23', 50); + expect(result).toBe(23); + }); + + it('returns default value for empty string', () => { + const result = parseUrlInt('', 50); + expect(result).toBe(50); + }); + + it('returns default value for non-numeric string', () => { + const result = parseUrlInt('abc', 50); + expect(result).toBe(50); + }); +}); diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/index.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/index.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_is_paused.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/parse_is_paused.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_is_paused.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/parse_is_paused.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_url_int.ts b/x-pack/plugins/uptime/public/lib/helper/url_params/parse_url_int.ts similarity index 87% rename from x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_url_int.ts rename to x-pack/plugins/uptime/public/lib/helper/url_params/parse_url_int.ts index b1a4d0a2aba0d8..0e5363527b5163 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_url_int.ts +++ b/x-pack/plugins/uptime/public/lib/helper/url_params/parse_url_int.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// TODO: add a comment explaining the purpose of this function export const parseUrlInt = (value: string | undefined, defaultValue: number): number => { const parsed = parseInt(value || '', 10); return isNaN(parsed) ? defaultValue : parsed; diff --git a/x-pack/legacy/plugins/uptime/public/lib/index.ts b/x-pack/plugins/uptime/public/lib/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/index.ts rename to x-pack/plugins/uptime/public/lib/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/lib/lib.ts b/x-pack/plugins/uptime/public/lib/lib.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/lib/lib.ts rename to x-pack/plugins/uptime/public/lib/lib.ts diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap b/x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap rename to x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/not_found.test.tsx.snap b/x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/not_found.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/not_found.test.tsx.snap rename to x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/not_found.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/overview.test.tsx.snap b/x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/overview.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/overview.test.tsx.snap rename to x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/overview.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap b/x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap rename to x-pack/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/monitor.test.tsx b/x-pack/plugins/uptime/public/pages/__tests__/monitor.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/__tests__/monitor.test.tsx rename to x-pack/plugins/uptime/public/pages/__tests__/monitor.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/not_found.test.tsx b/x-pack/plugins/uptime/public/pages/__tests__/not_found.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/__tests__/not_found.test.tsx rename to x-pack/plugins/uptime/public/pages/__tests__/not_found.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/overview.test.tsx b/x-pack/plugins/uptime/public/pages/__tests__/overview.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/__tests__/overview.test.tsx rename to x-pack/plugins/uptime/public/pages/__tests__/overview.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/page_header.test.tsx b/x-pack/plugins/uptime/public/pages/__tests__/page_header.test.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/__tests__/page_header.test.tsx rename to x-pack/plugins/uptime/public/pages/__tests__/page_header.test.tsx diff --git a/x-pack/legacy/plugins/uptime/public/pages/index.ts b/x-pack/plugins/uptime/public/pages/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/index.ts rename to x-pack/plugins/uptime/public/pages/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx b/x-pack/plugins/uptime/public/pages/monitor.tsx similarity index 87% rename from x-pack/legacy/plugins/uptime/public/pages/monitor.tsx rename to x-pack/plugins/uptime/public/pages/monitor.tsx index 4495be9b24dc1f..8a309db75acd23 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx +++ b/x-pack/plugins/uptime/public/pages/monitor.tsx @@ -7,14 +7,13 @@ import { EuiSpacer } from '@elastic/eui'; import React from 'react'; import { useSelector } from 'react-redux'; -import { useTrackPageview } from '../../../../../plugins/observability/public'; import { monitorStatusSelector } from '../state/selectors'; import { PageHeader } from './page_header'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; +import { useTrackPageview } from '../../../observability/public'; import { useMonitorId, useUptimeTelemetry, UptimePage } from '../hooks'; import { MonitorCharts } from '../components/monitor'; -import { MonitorStatusDetails } from '../components/monitor'; -import { PingList } from '../components/monitor'; +import { MonitorStatusDetails, PingList } from '../components/monitor'; export const MonitorPage: React.FC = () => { const monitorId = useMonitorId(); diff --git a/x-pack/legacy/plugins/uptime/public/pages/not_found.tsx b/x-pack/plugins/uptime/public/pages/not_found.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/not_found.tsx rename to x-pack/plugins/uptime/public/pages/not_found.tsx diff --git a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx b/x-pack/plugins/uptime/public/pages/overview.tsx similarity index 96% rename from x-pack/legacy/plugins/uptime/public/pages/overview.tsx rename to x-pack/plugins/uptime/public/pages/overview.tsx index adc36efa6f7db1..fefd804cbfabf0 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx +++ b/x-pack/plugins/uptime/public/pages/overview.tsx @@ -10,11 +10,11 @@ import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { useUptimeTelemetry, UptimePage, useGetUrlParams } from '../hooks'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; -import { useTrackPageview } from '../../../../../plugins/observability/public'; -import { DataPublicPluginSetup, IIndexPattern } from '../../../../../../src/plugins/data/public'; -import { useUpdateKueryString } from '../hooks'; import { PageHeader } from './page_header'; +import { DataPublicPluginSetup, IIndexPattern } from '../../../../../src/plugins/data/public'; +import { useUpdateKueryString } from '../hooks'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; +import { useTrackPageview } from '../../../observability/public'; import { MonitorList } from '../components/overview/monitor_list/monitor_list_container'; import { EmptyState, FilterGroup, KueryBar, ParsingErrorCallout } from '../components/overview'; import { StatusPanel } from '../components/overview/status_panel'; diff --git a/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx b/x-pack/plugins/uptime/public/pages/page_header.tsx similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/page_header.tsx rename to x-pack/plugins/uptime/public/pages/page_header.tsx diff --git a/x-pack/legacy/plugins/uptime/public/pages/settings.tsx b/x-pack/plugins/uptime/public/pages/settings.tsx similarity index 98% rename from x-pack/legacy/plugins/uptime/public/pages/settings.tsx rename to x-pack/plugins/uptime/public/pages/settings.tsx index d8c2a780928541..52096a49435d72 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/settings.tsx +++ b/x-pack/plugins/uptime/public/pages/settings.tsx @@ -24,7 +24,7 @@ import { getDynamicSettings, setDynamicSettings } from '../state/actions/dynamic import { DynamicSettings } from '../../common/runtime_types'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { OVERVIEW_ROUTE } from '../../common/constants'; -import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; +import { useKibana } from '../../../../../src/plugins/kibana_react/public'; import { UptimePage, useUptimeTelemetry } from '../hooks'; import { IndicesForm } from '../components/settings/indices_form'; import { diff --git a/x-pack/legacy/plugins/uptime/public/pages/translations.ts b/x-pack/plugins/uptime/public/pages/translations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/pages/translations.ts rename to x-pack/plugins/uptime/public/pages/translations.ts diff --git a/x-pack/legacy/plugins/uptime/public/routes.tsx b/x-pack/plugins/uptime/public/routes.tsx similarity index 93% rename from x-pack/legacy/plugins/uptime/public/routes.tsx rename to x-pack/plugins/uptime/public/routes.tsx index b5e20ef8a70a9b..eb0587c0417a2b 100644 --- a/x-pack/legacy/plugins/uptime/public/routes.tsx +++ b/x-pack/plugins/uptime/public/routes.tsx @@ -6,7 +6,7 @@ import React, { FC } from 'react'; import { Route, Switch } from 'react-router-dom'; -import { DataPublicPluginSetup } from '../../../../../src/plugins/data/public'; +import { DataPublicPluginSetup } from '../../../../src/plugins/data/public'; import { OverviewPage } from './components/overview/overview_container'; import { MONITOR_ROUTE, OVERVIEW_ROUTE, SETTINGS_ROUTE } from '../common/constants'; import { MonitorPage, NotFoundPage, SettingsPage } from './pages'; diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap b/x-pack/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap rename to x-pack/plugins/uptime/public/state/actions/__tests__/__snapshots__/overview_filters.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/__tests__/overview_filters.test.ts b/x-pack/plugins/uptime/public/state/actions/__tests__/overview_filters.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/__tests__/overview_filters.test.ts rename to x-pack/plugins/uptime/public/state/actions/__tests__/overview_filters.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/dynamic_settings.ts b/x-pack/plugins/uptime/public/state/actions/dynamic_settings.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/dynamic_settings.ts rename to x-pack/plugins/uptime/public/state/actions/dynamic_settings.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/index.ts b/x-pack/plugins/uptime/public/state/actions/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/index.ts rename to x-pack/plugins/uptime/public/state/actions/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/index_patternts.ts b/x-pack/plugins/uptime/public/state/actions/index_patternts.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/index_patternts.ts rename to x-pack/plugins/uptime/public/state/actions/index_patternts.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/index_status.ts b/x-pack/plugins/uptime/public/state/actions/index_status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/index_status.ts rename to x-pack/plugins/uptime/public/state/actions/index_status.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/ml_anomaly.ts b/x-pack/plugins/uptime/public/state/actions/ml_anomaly.ts similarity index 82% rename from x-pack/legacy/plugins/uptime/public/state/actions/ml_anomaly.ts rename to x-pack/plugins/uptime/public/state/actions/ml_anomaly.ts index 67c75314a7305b..441a3cefdf204d 100644 --- a/x-pack/legacy/plugins/uptime/public/state/actions/ml_anomaly.ts +++ b/x-pack/plugins/uptime/public/state/actions/ml_anomaly.ts @@ -6,15 +6,15 @@ import { createAction } from 'redux-actions'; import { createAsyncAction } from './utils'; -import { MlCapabilitiesResponse } from '../../../../../../plugins/ml/common/types/capabilities'; -import { AnomaliesTableRecord } from '../../../../../../plugins/ml/common/types/anomalies'; +import { MlCapabilitiesResponse } from '../../../../../plugins/ml/common/types/capabilities'; +import { AnomaliesTableRecord } from '../../../../../plugins/ml/common/types/anomalies'; import { CreateMLJobSuccess, DeleteJobResults, MonitorIdParam, HeartbeatIndicesParam, } from './types'; -import { JobExistResult } from '../../../../../../plugins/ml/common/types/data_recognizer'; +import { JobExistResult } from '../../../../../plugins/ml/common/types/data_recognizer'; export const resetMLState = createAction('RESET_ML_STATE'); diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/monitor.ts b/x-pack/plugins/uptime/public/state/actions/monitor.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/monitor.ts rename to x-pack/plugins/uptime/public/state/actions/monitor.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/monitor_duration.ts b/x-pack/plugins/uptime/public/state/actions/monitor_duration.ts similarity index 90% rename from x-pack/legacy/plugins/uptime/public/state/actions/monitor_duration.ts rename to x-pack/plugins/uptime/public/state/actions/monitor_duration.ts index 9a2db5be60b12a..524044f873687a 100644 --- a/x-pack/legacy/plugins/uptime/public/state/actions/monitor_duration.ts +++ b/x-pack/plugins/uptime/public/state/actions/monitor_duration.ts @@ -7,7 +7,7 @@ import { createAction } from 'redux-actions'; import { QueryParams } from './types'; import { MonitorDurationResult } from '../../../common/types'; -import { IHttpFetchError } from '../../../../../../../target/types/core/public/http'; +import { IHttpFetchError } from '../../../../../../target/types/core/public/http'; type MonitorQueryParams = QueryParams & { monitorId: string }; diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/monitor_list.ts b/x-pack/plugins/uptime/public/state/actions/monitor_list.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/monitor_list.ts rename to x-pack/plugins/uptime/public/state/actions/monitor_list.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/monitor_status.ts b/x-pack/plugins/uptime/public/state/actions/monitor_status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/monitor_status.ts rename to x-pack/plugins/uptime/public/state/actions/monitor_status.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/overview_filters.ts b/x-pack/plugins/uptime/public/state/actions/overview_filters.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/overview_filters.ts rename to x-pack/plugins/uptime/public/state/actions/overview_filters.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/ping.ts b/x-pack/plugins/uptime/public/state/actions/ping.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/ping.ts rename to x-pack/plugins/uptime/public/state/actions/ping.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/snapshot.ts b/x-pack/plugins/uptime/public/state/actions/snapshot.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/snapshot.ts rename to x-pack/plugins/uptime/public/state/actions/snapshot.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/types.ts b/x-pack/plugins/uptime/public/state/actions/types.ts similarity index 94% rename from x-pack/legacy/plugins/uptime/public/state/actions/types.ts rename to x-pack/plugins/uptime/public/state/actions/types.ts index 41381afd31453f..dee2df77707d28 100644 --- a/x-pack/legacy/plugins/uptime/public/state/actions/types.ts +++ b/x-pack/plugins/uptime/public/state/actions/types.ts @@ -5,7 +5,7 @@ */ import { Action } from 'redux-actions'; -import { IHttpFetchError } from '../../../../../../../target/types/core/public/http'; +import { IHttpFetchError } from '../../../../../../target/types/core/public/http'; export interface AsyncAction { get: (payload: Payload) => Action; diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/ui.ts b/x-pack/plugins/uptime/public/state/actions/ui.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/actions/ui.ts rename to x-pack/plugins/uptime/public/state/actions/ui.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/actions/utils.ts b/x-pack/plugins/uptime/public/state/actions/utils.ts similarity index 90% rename from x-pack/legacy/plugins/uptime/public/state/actions/utils.ts rename to x-pack/plugins/uptime/public/state/actions/utils.ts index a5adb96731f330..8ce4cf011406be 100644 --- a/x-pack/legacy/plugins/uptime/public/state/actions/utils.ts +++ b/x-pack/plugins/uptime/public/state/actions/utils.ts @@ -6,7 +6,7 @@ import { createAction } from 'redux-actions'; import { AsyncAction, AsyncAction1 } from './types'; -import { IHttpFetchError } from '../../../../../../../target/types/core/public/http'; +import { IHttpFetchError } from '../../../../../../target/types/core/public/http'; export function createAsyncAction( actionStr: string diff --git a/x-pack/legacy/plugins/uptime/public/state/api/__tests__/__snapshots__/snapshot.test.ts.snap b/x-pack/plugins/uptime/public/state/api/__tests__/__snapshots__/snapshot.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/__tests__/__snapshots__/snapshot.test.ts.snap rename to x-pack/plugins/uptime/public/state/api/__tests__/__snapshots__/snapshot.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/state/api/__tests__/ml_anomaly.test.ts b/x-pack/plugins/uptime/public/state/api/__tests__/ml_anomaly.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/__tests__/ml_anomaly.test.ts rename to x-pack/plugins/uptime/public/state/api/__tests__/ml_anomaly.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/__tests__/snapshot.test.ts b/x-pack/plugins/uptime/public/state/api/__tests__/snapshot.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/__tests__/snapshot.test.ts rename to x-pack/plugins/uptime/public/state/api/__tests__/snapshot.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/dynamic_settings.ts b/x-pack/plugins/uptime/public/state/api/dynamic_settings.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/dynamic_settings.ts rename to x-pack/plugins/uptime/public/state/api/dynamic_settings.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/index.ts b/x-pack/plugins/uptime/public/state/api/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/index.ts rename to x-pack/plugins/uptime/public/state/api/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/index_pattern.ts b/x-pack/plugins/uptime/public/state/api/index_pattern.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/index_pattern.ts rename to x-pack/plugins/uptime/public/state/api/index_pattern.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/index_status.ts b/x-pack/plugins/uptime/public/state/api/index_status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/index_status.ts rename to x-pack/plugins/uptime/public/state/api/index_status.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/ml_anomaly.ts b/x-pack/plugins/uptime/public/state/api/ml_anomaly.ts similarity index 92% rename from x-pack/legacy/plugins/uptime/public/state/api/ml_anomaly.ts rename to x-pack/plugins/uptime/public/state/api/ml_anomaly.ts index ca324895c26dbd..c4ecb769abefce 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/ml_anomaly.ts +++ b/x-pack/plugins/uptime/public/state/api/ml_anomaly.ts @@ -8,15 +8,15 @@ import moment from 'moment'; import { apiService } from './utils'; import { AnomalyRecords, AnomalyRecordsParams } from '../actions'; import { API_URLS, ML_JOB_ID, ML_MODULE_ID } from '../../../common/constants'; -import { MlCapabilitiesResponse } from '../../../../../../plugins/ml/common/types/capabilities'; +import { MlCapabilitiesResponse } from '../../../../../plugins/ml/common/types/capabilities'; import { CreateMLJobSuccess, DeleteJobResults, MonitorIdParam, HeartbeatIndicesParam, } from '../actions/types'; -import { DataRecognizerConfigResponse } from '../../../../../../plugins/ml/common/types/modules'; -import { JobExistResult } from '../../../../../../plugins/ml/common/types/data_recognizer'; +import { DataRecognizerConfigResponse } from '../../../../../plugins/ml/common/types/modules'; +import { JobExistResult } from '../../../../../plugins/ml/common/types/data_recognizer'; const getJobPrefix = (monitorId: string) => { // ML App doesn't support upper case characters in job name diff --git a/x-pack/legacy/plugins/uptime/public/state/api/monitor.ts b/x-pack/plugins/uptime/public/state/api/monitor.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/monitor.ts rename to x-pack/plugins/uptime/public/state/api/monitor.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts b/x-pack/plugins/uptime/public/state/api/monitor_duration.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/monitor_duration.ts rename to x-pack/plugins/uptime/public/state/api/monitor_duration.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/monitor_list.ts b/x-pack/plugins/uptime/public/state/api/monitor_list.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/monitor_list.ts rename to x-pack/plugins/uptime/public/state/api/monitor_list.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/monitor_status.ts b/x-pack/plugins/uptime/public/state/api/monitor_status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/monitor_status.ts rename to x-pack/plugins/uptime/public/state/api/monitor_status.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/overview_filters.ts b/x-pack/plugins/uptime/public/state/api/overview_filters.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/overview_filters.ts rename to x-pack/plugins/uptime/public/state/api/overview_filters.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/ping.ts b/x-pack/plugins/uptime/public/state/api/ping.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/ping.ts rename to x-pack/plugins/uptime/public/state/api/ping.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/snapshot.ts b/x-pack/plugins/uptime/public/state/api/snapshot.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/snapshot.ts rename to x-pack/plugins/uptime/public/state/api/snapshot.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/types.ts b/x-pack/plugins/uptime/public/state/api/types.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/api/types.ts rename to x-pack/plugins/uptime/public/state/api/types.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/api/utils.ts b/x-pack/plugins/uptime/public/state/api/utils.ts similarity index 95% rename from x-pack/legacy/plugins/uptime/public/state/api/utils.ts rename to x-pack/plugins/uptime/public/state/api/utils.ts index e67efa8570c110..acd9bec5a74bcb 100644 --- a/x-pack/legacy/plugins/uptime/public/state/api/utils.ts +++ b/x-pack/plugins/uptime/public/state/api/utils.ts @@ -6,7 +6,7 @@ import { PathReporter } from 'io-ts/lib/PathReporter'; import { isRight } from 'fp-ts/lib/Either'; -import { HttpFetchQuery, HttpSetup } from '../../../../../../../target/types/core/public'; +import { HttpFetchQuery, HttpSetup } from '../../../../../../target/types/core/public'; class ApiService { private static instance: ApiService; diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/__tests__/fetch_effect.test.ts b/x-pack/plugins/uptime/public/state/effects/__tests__/fetch_effect.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/__tests__/fetch_effect.test.ts rename to x-pack/plugins/uptime/public/state/effects/__tests__/fetch_effect.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/dynamic_settings.ts b/x-pack/plugins/uptime/public/state/effects/dynamic_settings.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/dynamic_settings.ts rename to x-pack/plugins/uptime/public/state/effects/dynamic_settings.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/fetch_effect.ts b/x-pack/plugins/uptime/public/state/effects/fetch_effect.ts similarity index 94% rename from x-pack/legacy/plugins/uptime/public/state/effects/fetch_effect.ts rename to x-pack/plugins/uptime/public/state/effects/fetch_effect.ts index b0734cb5ccabbc..0aa85609fe4f06 100644 --- a/x-pack/legacy/plugins/uptime/public/state/effects/fetch_effect.ts +++ b/x-pack/plugins/uptime/public/state/effects/fetch_effect.ts @@ -6,7 +6,7 @@ import { call, put } from 'redux-saga/effects'; import { Action } from 'redux-actions'; -import { IHttpFetchError } from '../../../../../../../target/types/core/public/http'; +import { IHttpFetchError } from '../../../../../../target/types/core/public/http'; /** * Factory function for a fetch effect. It expects three action creators, diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/index.ts b/x-pack/plugins/uptime/public/state/effects/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/index.ts rename to x-pack/plugins/uptime/public/state/effects/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/index_pattern.ts b/x-pack/plugins/uptime/public/state/effects/index_pattern.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/index_pattern.ts rename to x-pack/plugins/uptime/public/state/effects/index_pattern.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/index_status.ts b/x-pack/plugins/uptime/public/state/effects/index_status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/index_status.ts rename to x-pack/plugins/uptime/public/state/effects/index_status.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/ml_anomaly.ts b/x-pack/plugins/uptime/public/state/effects/ml_anomaly.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/ml_anomaly.ts rename to x-pack/plugins/uptime/public/state/effects/ml_anomaly.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/monitor.ts b/x-pack/plugins/uptime/public/state/effects/monitor.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/monitor.ts rename to x-pack/plugins/uptime/public/state/effects/monitor.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/monitor_duration.ts b/x-pack/plugins/uptime/public/state/effects/monitor_duration.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/monitor_duration.ts rename to x-pack/plugins/uptime/public/state/effects/monitor_duration.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/monitor_list.ts b/x-pack/plugins/uptime/public/state/effects/monitor_list.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/monitor_list.ts rename to x-pack/plugins/uptime/public/state/effects/monitor_list.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/monitor_status.ts b/x-pack/plugins/uptime/public/state/effects/monitor_status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/monitor_status.ts rename to x-pack/plugins/uptime/public/state/effects/monitor_status.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/overview_filters.ts b/x-pack/plugins/uptime/public/state/effects/overview_filters.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/overview_filters.ts rename to x-pack/plugins/uptime/public/state/effects/overview_filters.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/ping.ts b/x-pack/plugins/uptime/public/state/effects/ping.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/ping.ts rename to x-pack/plugins/uptime/public/state/effects/ping.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/snapshot.ts b/x-pack/plugins/uptime/public/state/effects/snapshot.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/effects/snapshot.ts rename to x-pack/plugins/uptime/public/state/effects/snapshot.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/index.ts b/x-pack/plugins/uptime/public/state/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/index.ts rename to x-pack/plugins/uptime/public/state/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/kibana_service.ts b/x-pack/plugins/uptime/public/state/kibana_service.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/kibana_service.ts rename to x-pack/plugins/uptime/public/state/kibana_service.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/__tests__/__snapshots__/snapshot.test.ts.snap b/x-pack/plugins/uptime/public/state/reducers/__tests__/__snapshots__/snapshot.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/__tests__/__snapshots__/snapshot.test.ts.snap rename to x-pack/plugins/uptime/public/state/reducers/__tests__/__snapshots__/snapshot.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/__tests__/__snapshots__/ui.test.ts.snap b/x-pack/plugins/uptime/public/state/reducers/__tests__/__snapshots__/ui.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/__tests__/__snapshots__/ui.test.ts.snap rename to x-pack/plugins/uptime/public/state/reducers/__tests__/__snapshots__/ui.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/__tests__/snapshot.test.ts b/x-pack/plugins/uptime/public/state/reducers/__tests__/snapshot.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/__tests__/snapshot.test.ts rename to x-pack/plugins/uptime/public/state/reducers/__tests__/snapshot.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/__tests__/ui.test.ts b/x-pack/plugins/uptime/public/state/reducers/__tests__/ui.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/__tests__/ui.test.ts rename to x-pack/plugins/uptime/public/state/reducers/__tests__/ui.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/dynamic_settings.ts b/x-pack/plugins/uptime/public/state/reducers/dynamic_settings.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/dynamic_settings.ts rename to x-pack/plugins/uptime/public/state/reducers/dynamic_settings.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/index.ts b/x-pack/plugins/uptime/public/state/reducers/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/index.ts rename to x-pack/plugins/uptime/public/state/reducers/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/index_pattern.ts b/x-pack/plugins/uptime/public/state/reducers/index_pattern.ts similarity index 92% rename from x-pack/legacy/plugins/uptime/public/state/reducers/index_pattern.ts rename to x-pack/plugins/uptime/public/state/reducers/index_pattern.ts index bc482e2f35c451..b357f5a904ea63 100644 --- a/x-pack/legacy/plugins/uptime/public/state/reducers/index_pattern.ts +++ b/x-pack/plugins/uptime/public/state/reducers/index_pattern.ts @@ -5,7 +5,7 @@ */ import { handleActions, Action } from 'redux-actions'; import { getIndexPattern, getIndexPatternSuccess, getIndexPatternFail } from '../actions'; -import { IIndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../src/plugins/data/common/index_patterns'; export interface IndexPatternState { index_pattern: IIndexPattern | null; diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/index_status.ts b/x-pack/plugins/uptime/public/state/reducers/index_status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/index_status.ts rename to x-pack/plugins/uptime/public/state/reducers/index_status.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/ml_anomaly.ts b/x-pack/plugins/uptime/public/state/reducers/ml_anomaly.ts similarity index 88% rename from x-pack/legacy/plugins/uptime/public/state/reducers/ml_anomaly.ts rename to x-pack/plugins/uptime/public/state/reducers/ml_anomaly.ts index df5e825c3488b9..61e03a95929211 100644 --- a/x-pack/legacy/plugins/uptime/public/state/reducers/ml_anomaly.ts +++ b/x-pack/plugins/uptime/public/state/reducers/ml_anomaly.ts @@ -15,11 +15,11 @@ import { getMLCapabilitiesAction, } from '../actions'; import { getAsyncInitialState, handleAsyncAction } from './utils'; -import { IHttpFetchError } from '../../../../../../../target/types/core/public/http'; +import { IHttpFetchError } from '../../../../../../target/types/core/public/http'; import { AsyncInitialState } from './types'; -import { MlCapabilitiesResponse } from '../../../../../../plugins/ml/common/types/capabilities'; +import { MlCapabilitiesResponse } from '../../../../../plugins/ml/common/types/capabilities'; import { CreateMLJobSuccess, DeleteJobResults } from '../actions/types'; -import { JobExistResult } from '../../../../../../plugins/ml/common/types/data_recognizer'; +import { JobExistResult } from '../../../../../plugins/ml/common/types/data_recognizer'; export interface MLJobState { mlJob: AsyncInitialState; diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/monitor.ts b/x-pack/plugins/uptime/public/state/reducers/monitor.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/monitor.ts rename to x-pack/plugins/uptime/public/state/reducers/monitor.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/monitor_duration.ts b/x-pack/plugins/uptime/public/state/reducers/monitor_duration.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/monitor_duration.ts rename to x-pack/plugins/uptime/public/state/reducers/monitor_duration.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/monitor_list.ts b/x-pack/plugins/uptime/public/state/reducers/monitor_list.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/monitor_list.ts rename to x-pack/plugins/uptime/public/state/reducers/monitor_list.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/monitor_status.ts b/x-pack/plugins/uptime/public/state/reducers/monitor_status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/monitor_status.ts rename to x-pack/plugins/uptime/public/state/reducers/monitor_status.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/overview_filters.ts b/x-pack/plugins/uptime/public/state/reducers/overview_filters.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/overview_filters.ts rename to x-pack/plugins/uptime/public/state/reducers/overview_filters.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/ping.ts b/x-pack/plugins/uptime/public/state/reducers/ping.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/ping.ts rename to x-pack/plugins/uptime/public/state/reducers/ping.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/ping_list.ts b/x-pack/plugins/uptime/public/state/reducers/ping_list.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/ping_list.ts rename to x-pack/plugins/uptime/public/state/reducers/ping_list.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/snapshot.ts b/x-pack/plugins/uptime/public/state/reducers/snapshot.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/snapshot.ts rename to x-pack/plugins/uptime/public/state/reducers/snapshot.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/types.ts b/x-pack/plugins/uptime/public/state/reducers/types.ts similarity index 81% rename from x-pack/legacy/plugins/uptime/public/state/reducers/types.ts rename to x-pack/plugins/uptime/public/state/reducers/types.ts index 88995a2f5dd70c..c81ee6875f305a 100644 --- a/x-pack/legacy/plugins/uptime/public/state/reducers/types.ts +++ b/x-pack/plugins/uptime/public/state/reducers/types.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IHttpFetchError } from '../../../../../../../target/types/core/public/http'; +import { IHttpFetchError } from '../../../../../../target/types/core/public/http'; export interface AsyncInitialState { data: ReduceStateType | null; diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/ui.ts b/x-pack/plugins/uptime/public/state/reducers/ui.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/ui.ts rename to x-pack/plugins/uptime/public/state/reducers/ui.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/utils.ts b/x-pack/plugins/uptime/public/state/reducers/utils.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/reducers/utils.ts rename to x-pack/plugins/uptime/public/state/reducers/utils.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/selectors/__tests__/index.test.ts b/x-pack/plugins/uptime/public/state/selectors/__tests__/index.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/selectors/__tests__/index.test.ts rename to x-pack/plugins/uptime/public/state/selectors/__tests__/index.test.ts diff --git a/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts b/x-pack/plugins/uptime/public/state/selectors/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/public/state/selectors/index.ts rename to x-pack/plugins/uptime/public/state/selectors/index.ts diff --git a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx b/x-pack/plugins/uptime/public/uptime_app.tsx similarity index 75% rename from x-pack/legacy/plugins/uptime/public/uptime_app.tsx rename to x-pack/plugins/uptime/public/uptime_app.tsx index 92775a26638633..0d18f959230d11 100644 --- a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx +++ b/x-pack/plugins/uptime/public/uptime_app.tsx @@ -10,13 +10,14 @@ import React, { useEffect } from 'react'; import { Provider as ReduxProvider } from 'react-redux'; import { BrowserRouter as Router } from 'react-router-dom'; import { I18nStart, ChromeBreadcrumb, CoreStart } from 'src/core/public'; -import { PluginsSetup } from 'ui/new_platform/new_platform'; -import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; +import { KibanaContextProvider } from '../../../../src/plugins/kibana_react/public'; +import { ClientPluginsSetup, ClientPluginsStart } from './apps/plugin'; import { UMUpdateBadge } from './lib/lib'; import { UptimeRefreshContextProvider, UptimeSettingsContextProvider, UptimeThemeContextProvider, + UptimeStartupPluginsContextProvider, } from './contexts'; import { CommonlyUsedRange } from './components/common/uptime_date_picker'; import { store } from './state'; @@ -47,7 +48,8 @@ export interface UptimeAppProps { isInfraAvailable: boolean; isLogsAvailable: boolean; kibanaBreadcrumbs: ChromeBreadcrumb[]; - plugins: PluginsSetup; + plugins: ClientPluginsSetup; + startPlugins: ClientPluginsStart; routerBasename: string; setBadge: UMUpdateBadge; renderGlobalHelpControls(): void; @@ -66,6 +68,7 @@ const Application = (props: UptimeAppProps) => { renderGlobalHelpControls, routerBasename, setBadge, + startPlugins, } = props; useEffect(() => { @@ -87,7 +90,6 @@ const Application = (props: UptimeAppProps) => { kibanaService.core = core; - // @ts-ignore store.dispatch(setBasePath(basePath)); return ( @@ -99,17 +101,19 @@ const Application = (props: UptimeAppProps) => { - - -
- - -
-
-
+ + + +
+ + +
+
+
+
diff --git a/x-pack/plugins/uptime/server/kibana.index.ts b/x-pack/plugins/uptime/server/kibana.index.ts index 725b53aeca02db..d68bbabe82b861 100644 --- a/x-pack/plugins/uptime/server/kibana.index.ts +++ b/x-pack/plugins/uptime/server/kibana.index.ts @@ -5,7 +5,7 @@ */ import { Request, Server } from 'hapi'; -import { PLUGIN } from '../../../legacy/plugins/uptime/common/constants'; +import { PLUGIN } from '../common/constants'; import { compose } from './lib/compose/kibana'; import { initUptimeServer } from './uptime_server'; import { UptimeCorePlugins, UptimeCoreSetup } from './lib/adapters/framework'; diff --git a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index 98c6be5aa3c8e8..f4d1c72770494d 100644 --- a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -13,7 +13,7 @@ import { } from 'src/core/server'; import { UMKibanaRoute } from '../../../rest_api'; import { PluginSetupContract } from '../../../../../features/server'; -import { DynamicSettings } from '../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { DynamicSettings } from '../../../../common/runtime_types'; export type APICaller = ( endpoint: string, @@ -31,7 +31,7 @@ export type UMSavedObjectsQueryFn = ( ) => Promise | T; export interface UptimeCoreSetup { - route: IRouter; + router: IRouter; } export interface UptimeCorePlugins { diff --git a/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts index 0176471aec1be2..46f46720d4c04a 100644 --- a/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -21,10 +21,10 @@ export class UMKibanaBackendFrameworkAdapter implements UMBackendFrameworkAdapte }; switch (method) { case 'GET': - this.server.route.get(routeDefinition, handler); + this.server.router.get(routeDefinition, handler); break; case 'POST': - this.server.route.post(routeDefinition, handler); + this.server.router.post(routeDefinition, handler); break; default: throw new Error(`Handler for method ${method} is not defined`); diff --git a/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts b/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts index 4f4c6e3011ad14..24da3f3fa4d067 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/__tests__/status_check.test.ts @@ -16,7 +16,7 @@ import { AlertType } from '../../../../../alerting/server'; import { IRouter } from 'kibana/server'; import { UMServerLibs } from '../../lib'; import { UptimeCoreSetup } from '../../adapters'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../../legacy/plugins/uptime/common/constants'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; import { alertsMock, AlertServicesMock } from '../../../../../alerting/server/mocks'; /** @@ -27,10 +27,10 @@ import { alertsMock, AlertServicesMock } from '../../../../../alerting/server/mo * so we don't have to mock them all for each test. */ const bootstrapDependencies = (customRequests?: any) => { - const route: IRouter = {} as IRouter; + const router: IRouter = {} as IRouter; // these server/libs parameters don't have any functionality, which is fine // because we aren't testing them here - const server: UptimeCoreSetup = { route }; + const server: UptimeCoreSetup = { router }; const libs: UMServerLibs = { requests: {} } as UMServerLibs; libs.requests = { ...libs.requests, ...customRequests }; return { server, libs }; diff --git a/x-pack/plugins/uptime/server/lib/alerts/status_check.ts b/x-pack/plugins/uptime/server/lib/alerts/status_check.ts index 829e6f92d37020..f9df559a3977ba 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/status_check.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/status_check.ts @@ -9,14 +9,14 @@ import { isRight } from 'fp-ts/lib/Either'; import { ThrowReporter } from 'io-ts/lib/ThrowReporter'; import { i18n } from '@kbn/i18n'; import { AlertExecutorOptions } from '../../../../alerting/server'; -import { ACTION_GROUP_DEFINITIONS } from '../../../../../legacy/plugins/uptime/common/constants'; import { UptimeAlertTypeFactory } from './types'; import { GetMonitorStatusResult } from '../requests'; import { StatusCheckExecutorParamsType, StatusCheckAlertStateType, StatusCheckAlertState, -} from '../../../../../legacy/plugins/uptime/common/runtime_types'; +} from '../../../common/runtime_types'; +import { ACTION_GROUP_DEFINITIONS } from '../../../common/constants'; import { savedObjectsAdapter } from '../saved_objects'; const { MONITOR_STATUS } = ACTION_GROUP_DEFINITIONS; diff --git a/x-pack/plugins/uptime/server/lib/helper/get_histogram_interval.ts b/x-pack/plugins/uptime/server/lib/helper/get_histogram_interval.ts index fb44f5727aab38..26515fb4b4c63b 100644 --- a/x-pack/plugins/uptime/server/lib/helper/get_histogram_interval.ts +++ b/x-pack/plugins/uptime/server/lib/helper/get_histogram_interval.ts @@ -5,7 +5,7 @@ */ import DateMath from '@elastic/datemath'; -import { QUERY } from '../../../../../legacy/plugins/uptime/common/constants'; +import { QUERY } from '../../../common/constants'; export const parseRelativeDate = (dateStr: string, options = {}) => { // We need this this parsing because if user selects This week or this date diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_certs.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_certs.test.ts index b49a6b22ff9768..894e2316dc927f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_certs.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_certs.test.ts @@ -5,7 +5,7 @@ */ import { getCerts } from '../get_certs'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../../legacy/plugins/uptime/common/constants'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; describe('getCerts', () => { let mockHits: any; diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts index 03e2bc7a44bd04..75bf5096bd9978 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts @@ -5,7 +5,7 @@ */ import { getLatestMonitor } from '../get_latest_monitor'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../../legacy/plugins/uptime/common/constants'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; describe('getLatestMonitor', () => { let expectedGetLatestSearchParams: any; diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts index 5d3f9ce8d4ad9d..45be1df3e8d3bf 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts @@ -7,7 +7,7 @@ import { set } from 'lodash'; import mockChartsData from './monitor_charts_mock.json'; import { getMonitorDurationChart } from '../get_monitor_duration'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../../legacy/plugins/uptime/common/constants'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; describe('ElasticsearchMonitorsAdapter', () => { it('getMonitorChartsData will provide expected filters', async () => { diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts index e47be617d7c994..82e624221c301c 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_status.test.ts @@ -6,8 +6,8 @@ import { elasticsearchServiceMock } from '../../../../../../../src/core/server/mocks'; import { getMonitorStatus } from '../get_monitor_status'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../../legacy/plugins/uptime/common/constants'; import { ScopedClusterClient } from 'src/core/server'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; interface BucketItemCriteria { monitor_id: string; diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts index 4de7d3ffd2a7d5..e456670a5e68de 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts @@ -5,7 +5,7 @@ */ import { getPingHistogram } from '../get_ping_histogram'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../../legacy/plugins/uptime/common/constants'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; describe('getPingHistogram', () => { const standardMockResponse: any = { diff --git a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts index abd3655cc64028..fd890a30cf7428 100644 --- a/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts @@ -6,7 +6,7 @@ import { getPings } from '../get_pings'; import { set } from 'lodash'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../../legacy/plugins/uptime/common/constants'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../common/constants'; describe('getAll', () => { let mockEsSearchResult: any; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_certs.ts b/x-pack/plugins/uptime/server/lib/requests/get_certs.ts index 4f99fbe94d54c7..b427e7cae1a7e8 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_certs.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_certs.ts @@ -5,7 +5,7 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { Cert, GetCertsParams } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { Cert, GetCertsParams } from '../../../common/runtime_types'; export const getCerts: UMElasticsearchQueryFn = async ({ callES, diff --git a/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts b/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts index 95d23ddcbf466e..dbe71cf689214f 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts @@ -5,7 +5,7 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { OverviewFilters } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { OverviewFilters } from '../../../common/runtime_types'; import { generateFilterAggs } from './generate_filter_aggs'; export interface GetFilterBarParams { diff --git a/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts b/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts index 6f7854d35b308b..7688f04f1acd95 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts @@ -5,7 +5,7 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { StatesIndexStatus } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { StatesIndexStatus } from '../../../common/runtime_types'; export const getIndexStatus: UMElasticsearchQueryFn<{}, StatesIndexStatus> = async ({ callES, diff --git a/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts index a8e9ccb875a08c..98ce449002f217 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts @@ -5,7 +5,7 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { Ping } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { Ping } from '../../../common/runtime_types'; export interface GetLatestMonitorParams { /** @member dateRangeStart timestamp bounds */ diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts index 4ce7176b57b199..cf4ffa339ddfc5 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts @@ -5,10 +5,7 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { - MonitorDetails, - MonitorError, -} from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { MonitorDetails, MonitorError } from '../../../common/runtime_types'; export interface GetMonitorDetailsParams { monitorId: string; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_duration.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_duration.ts index e9c745b0a87133..ea2a7e790652bd 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_duration.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_duration.ts @@ -5,11 +5,8 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { QUERY } from '../../../../../legacy/plugins/uptime/common/constants'; -import { - LocationDurationLine, - MonitorDurationResult, -} from '../../../../../legacy/plugins/uptime/common/types'; +import { LocationDurationLine, MonitorDurationResult } from '../../../common/types'; +import { QUERY } from '../../../common/constants'; export interface GetMonitorChartsParams { /** @member monitorId ID value for the selected monitor */ diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts index f49e404ffb084b..c8d3ca043edc50 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts @@ -5,11 +5,8 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { UNNAMED_LOCATION } from '../../../../../legacy/plugins/uptime/common/constants'; -import { - MonitorLocations, - MonitorLocation, -} from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { MonitorLocations, MonitorLocation } from '../../../common/runtime_types'; +import { UNNAMED_LOCATION } from '../../../common/constants'; /** * Fetch data for the monitor page title. diff --git a/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts index 4b40943a857051..b1791dd04861c4 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts @@ -4,15 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CONTEXT_DEFAULTS } from '../../../../../legacy/plugins/uptime/common/constants'; +import { CONTEXT_DEFAULTS } from '../../../common/constants'; import { fetchPage } from './search'; import { UMElasticsearchQueryFn } from '../adapters'; -import { - SortOrder, - CursorDirection, - MonitorSummary, -} from '../../../../../legacy/plugins/uptime/common/runtime_types'; - +import { MonitorSummary, SortOrder, CursorDirection } from '../../../common/runtime_types'; import { QueryContext } from './search'; export interface CursorPagination { diff --git a/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts index 5a8927764ea5c2..299913c8dff086 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts @@ -5,12 +5,9 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { QUERY } from '../../../../../legacy/plugins/uptime/common/constants'; import { getFilterClause } from '../helper'; -import { - HistogramResult, - HistogramQueryResult, -} from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { HistogramResult, HistogramQueryResult } from '../../../common/runtime_types'; +import { QUERY } from '../../../common/constants'; export interface GetPingHistogramParams { /** @member dateRangeStart timestamp bounds */ diff --git a/x-pack/plugins/uptime/server/lib/requests/get_pings.ts b/x-pack/plugins/uptime/server/lib/requests/get_pings.ts index 6eccfdb13cef74..a6a0e3c3d6542e 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_pings.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_pings.ts @@ -10,7 +10,7 @@ import { HttpResponseBody, PingsResponse, Ping, -} from '../../../../../legacy/plugins/uptime/common/runtime_types'; +} from '../../../common/runtime_types'; const DEFAULT_PAGE_SIZE = 25; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts b/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts index 01f2ad88161cf0..b57bc87d454183 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts @@ -5,8 +5,8 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { Snapshot } from '../../../../../legacy/plugins/uptime/common/runtime_types'; -import { CONTEXT_DEFAULTS } from '../../../../../legacy/plugins/uptime/common/constants'; +import { CONTEXT_DEFAULTS } from '../../../common/constants'; +import { Snapshot } from '../../../common/runtime_types'; import { QueryContext } from './search'; export interface GetSnapshotCountParams { diff --git a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts index 2a8f681ab34536..d4ad80c85ec3d5 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts @@ -12,7 +12,7 @@ import { MonitorGroupsPage, } from '../fetch_page'; import { QueryContext } from '../query_context'; -import { MonitorSummary } from '../../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { MonitorSummary } from '../../../../../common/runtime_types'; import { nextPagination, prevPagination, simpleQueryContext } from './test_helpers'; const simpleFixture: MonitorGroups[] = [ diff --git a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts index 84774cdeed8567..e53fff429dd8df 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts @@ -6,10 +6,7 @@ import { QueryContext } from '../query_context'; import { CursorPagination } from '../types'; -import { - CursorDirection, - SortOrder, -} from '../../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { CursorDirection, SortOrder } from '../../../../../common/runtime_types'; describe(QueryContext, () => { // 10 minute range diff --git a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts index 47034c21301164..40775bde1c7f5a 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts @@ -5,10 +5,7 @@ */ import { CursorPagination } from '../types'; -import { - CursorDirection, - SortOrder, -} from '../../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { CursorDirection, SortOrder } from '../../../../../common/runtime_types'; import { QueryContext } from '../query_context'; export const prevPagination = (key: any): CursorPagination => { diff --git a/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts b/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts index 4739c804d24e75..d21259fad77a66 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts @@ -6,14 +6,14 @@ import { get, sortBy } from 'lodash'; import { QueryContext } from './query_context'; -import { QUERY, STATES } from '../../../../../../legacy/plugins/uptime/common/constants'; +import { QUERY, STATES } from '../../../../common/constants'; import { Check, Histogram, MonitorSummary, CursorDirection, SortOrder, -} from '../../../../../../legacy/plugins/uptime/common/runtime_types'; +} from '../../../../common/runtime_types'; import { MonitorEnricher } from './fetch_page'; export const enrichMonitorGroups: MonitorEnricher = async ( diff --git a/x-pack/plugins/uptime/server/lib/requests/search/fetch_page.ts b/x-pack/plugins/uptime/server/lib/requests/search/fetch_page.ts index 84167840d5d9ba..bef8106ad1896c 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/fetch_page.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/fetch_page.ts @@ -7,12 +7,8 @@ import { flatten } from 'lodash'; import { CursorPagination } from './types'; import { QueryContext } from './query_context'; -import { QUERY } from '../../../../../../legacy/plugins/uptime/common/constants'; -import { - CursorDirection, - MonitorSummary, - SortOrder, -} from '../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { QUERY } from '../../../../common/constants'; +import { CursorDirection, MonitorSummary, SortOrder } from '../../../../common/runtime_types'; import { enrichMonitorGroups } from './enrich_monitor_groups'; import { MonitorGroupIterator } from './monitor_group_iterator'; diff --git a/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts b/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts index 3449febfa5b053..e60c52660915a1 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts @@ -5,7 +5,7 @@ */ import { get, set } from 'lodash'; -import { CursorDirection } from '../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { CursorDirection } from '../../../../common/runtime_types'; import { QueryContext } from './query_context'; // This is the first phase of the query. In it, we find the most recent check groups that matched the given query. diff --git a/x-pack/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts b/x-pack/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts index 31d9166eb1e73b..2fb95620282583 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts @@ -6,7 +6,7 @@ import { QueryContext } from './query_context'; import { fetchChunk } from './fetch_chunk'; -import { CursorDirection } from '../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { CursorDirection } from '../../../../common/runtime_types'; import { MonitorGroups } from './fetch_page'; import { CursorPagination } from './types'; diff --git a/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts b/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts index 43fc54fb258089..977c32ad1f984b 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts @@ -5,7 +5,7 @@ */ import { QueryContext } from './query_context'; -import { CursorDirection } from '../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { CursorDirection } from '../../../../common/runtime_types'; import { MonitorGroups, MonitorLocCheckGroup } from './fetch_page'; /** diff --git a/x-pack/plugins/uptime/server/lib/requests/search/types.ts b/x-pack/plugins/uptime/server/lib/requests/search/types.ts index 2ec52d400b5972..35e9647196454e 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/types.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/types.ts @@ -4,10 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - CursorDirection, - SortOrder, -} from '../../../../../../legacy/plugins/uptime/common/runtime_types'; +import { CursorDirection, SortOrder } from '../../../../common/runtime_types'; export interface CursorPagination { cursorKey?: any; diff --git a/x-pack/plugins/uptime/server/lib/requests/uptime_requests.ts b/x-pack/plugins/uptime/server/lib/requests/uptime_requests.ts index 84154429b91888..69507d2950cd84 100644 --- a/x-pack/plugins/uptime/server/lib/requests/uptime_requests.ts +++ b/x-pack/plugins/uptime/server/lib/requests/uptime_requests.ts @@ -8,10 +8,17 @@ import { UMElasticsearchQueryFn } from '../adapters'; import { HistogramResult, Ping, - PingsResponse as PingResults, + PingsResponse, GetCertsParams, GetPingsParams, -} from '../../../../../legacy/plugins/uptime/common/runtime_types'; + Cert, + OverviewFilters, + MonitorDetails, + MonitorLocations, + Snapshot, + StatesIndexStatus, +} from '../../../common/runtime_types'; +import { MonitorDurationResult } from '../../../common/types'; import { GetFilterBarParams, GetLatestMonitorParams, @@ -23,17 +30,8 @@ import { GetMonitorStatusParams, GetMonitorStatusResult, } from '.'; -import { - OverviewFilters, - MonitorDetails, - MonitorLocations, - Snapshot, - StatesIndexStatus, - Cert, -} from '../../../../../legacy/plugins/uptime/common/runtime_types'; import { GetMonitorStatesResult } from './get_monitor_states'; import { GetSnapshotCountParams } from './get_snapshot_counts'; -import { MonitorDurationResult } from '../../../../../legacy/plugins/uptime/common/types'; type ESQ = UMElasticsearchQueryFn; @@ -47,7 +45,7 @@ export interface UptimeRequests { getMonitorLocations: ESQ; getMonitorStates: ESQ; getMonitorStatus: ESQ; - getPings: ESQ; + getPings: ESQ; getPingHistogram: ESQ; getSnapshotCount: ESQ; getIndexStatus: ESQ<{}, StatesIndexStatus>; diff --git a/x-pack/plugins/uptime/server/lib/saved_objects.ts b/x-pack/plugins/uptime/server/lib/saved_objects.ts index d849fbd8ce0a8f..28b9eaad2cf6f0 100644 --- a/x-pack/plugins/uptime/server/lib/saved_objects.ts +++ b/x-pack/plugins/uptime/server/lib/saved_objects.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DynamicSettings } from '../../../../legacy/plugins/uptime/common/runtime_types'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../legacy/plugins/uptime/common/constants'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../common/constants'; +import { DynamicSettings } from '../../common/runtime_types'; import { SavedObjectsType, SavedObjectsErrorHelpers } from '../../../../../src/core/server'; import { UMSavedObjectsQueryFn } from './adapters'; diff --git a/x-pack/plugins/uptime/server/plugin.ts b/x-pack/plugins/uptime/server/plugin.ts index 7cc591a6b2db17..13d1ae216f2041 100644 --- a/x-pack/plugins/uptime/server/plugin.ts +++ b/x-pack/plugins/uptime/server/plugin.ts @@ -8,19 +8,20 @@ import { PluginInitializerContext, CoreStart, CoreSetup, + Plugin as PluginType, ISavedObjectsRepository, } from '../../../../src/core/server'; import { initServerWithKibana } from './kibana.index'; import { KibanaTelemetryAdapter, UptimeCorePlugins } from './lib/adapters'; import { umDynamicSettings } from './lib/saved_objects'; -export class Plugin { +export class Plugin implements PluginType { private savedObjectsClient?: ISavedObjectsRepository; constructor(_initializerContext: PluginInitializerContext) {} public setup(core: CoreSetup, plugins: UptimeCorePlugins) { - initServerWithKibana({ route: core.http.createRouter() }, plugins); + initServerWithKibana({ router: core.http.createRouter() }, plugins); core.savedObjects.registerType(umDynamicSettings); KibanaTelemetryAdapter.registerUsageCollector( plugins.usageCollection, @@ -28,7 +29,9 @@ export class Plugin { ); } - public start(_core: CoreStart, _plugins: any) { - this.savedObjectsClient = _core.savedObjects.createInternalRepository(); + public start(core: CoreStart, _plugins: any) { + this.savedObjectsClient = core.savedObjects.createInternalRepository(); } + + public stop() {} } diff --git a/x-pack/plugins/uptime/server/rest_api/certs.ts b/x-pack/plugins/uptime/server/rest_api/certs.ts index 31fb3f4ab96a78..f2e1700b23e7d8 100644 --- a/x-pack/plugins/uptime/server/rest_api/certs.ts +++ b/x-pack/plugins/uptime/server/rest_api/certs.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../lib/lib'; import { UMRestApiRouteFactory } from '.'; -import { API_URLS } from '../../../../legacy/plugins/uptime/common/constants/rest_api'; +import { API_URLS } from '../../common/constants'; const DEFAULT_INDEX = 0; const DEFAULT_SIZE = 25; diff --git a/x-pack/plugins/uptime/server/rest_api/dynamic_settings.ts b/x-pack/plugins/uptime/server/rest_api/dynamic_settings.ts index 3f4e2fc345182c..31833a25ee8acf 100644 --- a/x-pack/plugins/uptime/server/rest_api/dynamic_settings.ts +++ b/x-pack/plugins/uptime/server/rest_api/dynamic_settings.ts @@ -8,10 +8,7 @@ import { schema } from '@kbn/config-schema'; import { isRight } from 'fp-ts/lib/Either'; import { PathReporter } from 'io-ts/lib/PathReporter'; import { UMServerLibs } from '../lib/lib'; -import { - DynamicSettings, - DynamicSettingsType, -} from '../../../../legacy/plugins/uptime/common/runtime_types'; +import { DynamicSettings, DynamicSettingsType } from '../../common/runtime_types'; import { UMRestApiRouteFactory } from '.'; import { savedObjectsAdapter } from '../lib/saved_objects'; diff --git a/x-pack/plugins/uptime/server/rest_api/index_state/get_index_pattern.ts b/x-pack/plugins/uptime/server/rest_api/index_state/get_index_pattern.ts index 689a75c5903a64..26715f0ff37b64 100644 --- a/x-pack/plugins/uptime/server/rest_api/index_state/get_index_pattern.ts +++ b/x-pack/plugins/uptime/server/rest_api/index_state/get_index_pattern.ts @@ -6,7 +6,7 @@ import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export const createGetIndexPatternRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/index_state/get_index_status.ts b/x-pack/plugins/uptime/server/rest_api/index_state/get_index_status.ts index 8ed73d90b2389e..9a4280efa98f92 100644 --- a/x-pack/plugins/uptime/server/rest_api/index_state/get_index_status.ts +++ b/x-pack/plugins/uptime/server/rest_api/index_state/get_index_status.ts @@ -6,7 +6,7 @@ import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; +import { API_URLS } from '../../../common/constants'; export const createGetIndexStatusRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_list.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_list.ts index 5cb4e8a6241b74..60b3eafaa765e6 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_list.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_list.ts @@ -6,8 +6,7 @@ import { schema } from '@kbn/config-schema'; import { UMRestApiRouteFactory } from '../types'; -import { CONTEXT_DEFAULTS } from '../../../../../legacy/plugins/uptime/common/constants'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants/rest_api'; +import { API_URLS, CONTEXT_DEFAULTS } from '../../../common/constants'; export const createMonitorListRoute: UMRestApiRouteFactory = libs => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts index 66ce9871506d4e..a110209043a7e7 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export const createGetMonitorLocationsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_status.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_status.ts index 9cf1340fb94090..bb002f8a8c286c 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitor_status.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_status.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; +import { API_URLS } from '../../../common/constants'; export const createGetStatusBarRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts index 1cc010781457e2..69e719efb0719d 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export const createGetMonitorDetailsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/monitors/monitors_durations.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_durations.ts index 9743ced13350a4..34313211061b08 100644 --- a/x-pack/plugins/uptime/server/rest_api/monitors/monitors_durations.ts +++ b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_durations.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export const createGetMonitorDurationRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts b/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts index deac05f36c8dc9..00cbaf0d16723c 100644 --- a/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts +++ b/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; import { objectValuesToArrays } from '../../lib/helper'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; const arrayOrStringType = schema.maybe( schema.oneOf([schema.string(), schema.arrayOf(schema.string())]) diff --git a/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts b/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts index dceef5ecb78486..41078f735920b8 100644 --- a/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts +++ b/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants/rest_api'; +import { API_URLS } from '../../../common/constants'; export const createGetPingHistogramRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts b/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts index 80a887a7f64a9d..d97195a7fe2b17 100644 --- a/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts +++ b/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts @@ -9,8 +9,8 @@ import { isLeft } from 'fp-ts/lib/Either'; import { PathReporter } from 'io-ts/lib/PathReporter'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants/rest_api'; -import { GetPingsParamsType } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { API_URLS } from '../../../common/constants'; +import { GetPingsParamsType } from '../../../common/runtime_types'; export const createGetPingsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts index d870f492801171..7809e102a499f8 100644 --- a/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts +++ b/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UMServerLibs } from '../../lib/lib'; import { UMRestApiRouteFactory } from '../types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; +import { API_URLS } from '../../../common/constants'; export const createGetSnapshotCount: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ method: 'GET', diff --git a/x-pack/plugins/uptime/server/rest_api/telemetry/log_page_view.ts b/x-pack/plugins/uptime/server/rest_api/telemetry/log_page_view.ts index 4b2db71037071e..d8387e79e9089b 100644 --- a/x-pack/plugins/uptime/server/rest_api/telemetry/log_page_view.ts +++ b/x-pack/plugins/uptime/server/rest_api/telemetry/log_page_view.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { KibanaTelemetryAdapter } from '../../lib/adapters/telemetry'; import { UMRestApiRouteFactory } from '../types'; import { PageViewParams } from '../../lib/adapters/telemetry/types'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; +import { API_URLS } from '../../../common/constants'; export const createLogPageViewRoute: UMRestApiRouteFactory = () => ({ method: 'POST', diff --git a/x-pack/plugins/uptime/server/rest_api/types.ts b/x-pack/plugins/uptime/server/rest_api/types.ts index e05e7a4d7faf1a..8720b9dc60b12a 100644 --- a/x-pack/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/plugins/uptime/server/rest_api/types.ts @@ -15,8 +15,8 @@ import { KibanaRequest, KibanaResponseFactory, IKibanaResponse, -} from 'src/core/server'; -import { DynamicSettings } from '../../../../legacy/plugins/uptime/common/runtime_types'; +} from 'kibana/server'; +import { DynamicSettings } from '../../common/runtime_types'; import { UMServerLibs } from '../lib/lib'; /** diff --git a/x-pack/test/api_integration/apis/uptime/feature_controls.ts b/x-pack/test/api_integration/apis/uptime/feature_controls.ts index 6d125807e169d1..6c566ec7cb23b8 100644 --- a/x-pack/test/api_integration/apis/uptime/feature_controls.ts +++ b/x-pack/test/api_integration/apis/uptime/feature_controls.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; import { PINGS_DATE_RANGE_END, PINGS_DATE_RANGE_START } from './constants'; -import { API_URLS } from '../../../../legacy/plugins/uptime/common/constants'; +import { API_URLS } from '../../../../plugins/uptime/common/constants'; export default function featureControlsTests({ getService }: FtrProviderContext) { const supertest = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/uptime/rest/certs.ts b/x-pack/test/api_integration/apis/uptime/rest/certs.ts index 7510ea3f34d282..a3a15d8f8b0143 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/certs.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/certs.ts @@ -8,8 +8,8 @@ import expect from '@kbn/expect'; import moment from 'moment'; import { isRight } from 'fp-ts/lib/Either'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; -import { CertType } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { API_URLS } from '../../../../../plugins/uptime/common/constants'; +import { CertType } from '../../../../../plugins/uptime/common/runtime_types'; import { makeChecksWithStatus } from './helper/make_checks'; export default function({ getService }: FtrProviderContext) { diff --git a/x-pack/test/api_integration/apis/uptime/rest/doc_count.ts b/x-pack/test/api_integration/apis/uptime/rest/doc_count.ts index 5258426cf193c1..f343cd1da8788b 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/doc_count.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/doc_count.ts @@ -5,7 +5,7 @@ */ import { FtrProviderContext } from '../../../ftr_provider_context'; import { expectFixtureEql } from './helper/expect_fixture_eql'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; +import { API_URLS } from '../../../../../plugins/uptime/common/constants'; export default function({ getService }: FtrProviderContext) { describe('docCount query', () => { diff --git a/x-pack/test/api_integration/apis/uptime/rest/dynamic_settings.ts b/x-pack/test/api_integration/apis/uptime/rest/dynamic_settings.ts index ea980721b831bb..95caf50d1ca7a4 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/dynamic_settings.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/dynamic_settings.ts @@ -7,9 +7,8 @@ import expect from '@kbn/expect'; import { isRight } from 'fp-ts/lib/Either'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../legacy/plugins/uptime/common/constants'; -import { DynamicSettingsType } from '../../../../../legacy/plugins/uptime/common/runtime_types'; - +import { DynamicSettingsType } from '../../../../../plugins/uptime/common/runtime_types'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../../plugins/uptime/common/constants'; export default function({ getService }: FtrProviderContext) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/uptime/rest/monitor_states_generated.ts b/x-pack/test/api_integration/apis/uptime/rest/monitor_states_generated.ts index 3c17370532f915..c3d5849e028ab0 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/monitor_states_generated.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/monitor_states_generated.ts @@ -7,8 +7,8 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { makeChecksWithStatus } from './helper/make_checks'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; -import { MonitorSummary } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { MonitorSummary } from '../../../../../plugins/uptime/common/runtime_types'; +import { API_URLS } from '../../../../../plugins/uptime/common/constants'; export default function({ getService }: FtrProviderContext) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/uptime/rest/monitor_states_real_data.ts b/x-pack/test/api_integration/apis/uptime/rest/monitor_states_real_data.ts index f1e37bff405fd3..c5a691312f5250 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/monitor_states_real_data.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/monitor_states_real_data.ts @@ -7,8 +7,8 @@ import expect from '@kbn/expect'; import { isRight } from 'fp-ts/lib/Either'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; -import { MonitorSummaryResultType } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { MonitorSummaryResultType } from '../../../../../plugins/uptime/common/runtime_types'; +import { API_URLS } from '../../../../../plugins/uptime/common/constants'; interface ExpectedMonitorStatesPage { response: any; diff --git a/x-pack/test/api_integration/apis/uptime/rest/ping_list.ts b/x-pack/test/api_integration/apis/uptime/rest/ping_list.ts index a261763d5991f9..3d754d89cf9be0 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/ping_list.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/ping_list.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; import { isLeft } from 'fp-ts/lib/Either'; import { PathReporter } from 'io-ts/lib/PathReporter'; -import { PingsResponseType } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { PingsResponseType } from '../../../../../plugins/uptime/common/runtime_types'; import { FtrProviderContext } from '../../../ftr_provider_context'; function decodePingsResponseData(response: any) { diff --git a/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors.ts b/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors.ts index 017ef02afe5ea7..99e09aa5ce886a 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/telemetry_collectors.ts @@ -6,7 +6,7 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { API_URLS } from '../../../../../legacy/plugins/uptime/common/constants'; +import { API_URLS } from '../../../../../plugins/uptime/common/constants'; import { makeChecksWithStatus } from './helper/make_checks'; export default function({ getService }: FtrProviderContext) { diff --git a/x-pack/test/functional/apps/uptime/settings.ts b/x-pack/test/functional/apps/uptime/settings.ts index 64b6300e0df631..7a813a5cdfb526 100644 --- a/x-pack/test/functional/apps/uptime/settings.ts +++ b/x-pack/test/functional/apps/uptime/settings.ts @@ -6,8 +6,8 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../legacy/plugins/uptime/common/constants'; -import { DynamicSettings } from '../../../../legacy/plugins/uptime/common/runtime_types'; +import { DynamicSettings } from '../../../../plugins/uptime/common/runtime_types'; +import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../../plugins/uptime/common/constants'; import { makeChecks } from '../../../api_integration/apis/uptime/rest/helper/make_checks'; export default ({ getPageObjects, getService }: FtrProviderContext) => { diff --git a/x-pack/test/functional/services/uptime/settings.ts b/x-pack/test/functional/services/uptime/settings.ts index 9719152b62d354..96f5e45ce2ca47 100644 --- a/x-pack/test/functional/services/uptime/settings.ts +++ b/x-pack/test/functional/services/uptime/settings.ts @@ -5,7 +5,7 @@ */ import { FtrProviderContext } from '../../ftr_provider_context'; -import { DynamicSettings } from '../../../../legacy/plugins/uptime/common/runtime_types'; +import { DynamicSettings } from '../../../../plugins/uptime/common/runtime_types'; export function UptimeSettingsProvider({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); From a38c11cd10577a69d3c06ba7829358531a29ac90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Istv=C3=A1n=20Zolt=C3=A1n=20Szab=C3=B3?= Date: Wed, 29 Apr 2020 13:58:27 +0200 Subject: [PATCH 06/26] [ML] Changes Machine learning overview UI text (#64625) Co-Authored-By: Lisa Cawley --- .../components/analytics_panel/analytics_panel.tsx | 4 ++-- .../anomaly_detection_panel.tsx | 2 +- .../application/overview/components/sidebar.tsx | 13 ++----------- x-pack/plugins/translations/translations/ja-JP.json | 3 +-- x-pack/plugins/translations/translations/zh-CN.json | 3 +-- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/ml/public/application/overview/components/analytics_panel/analytics_panel.tsx b/x-pack/plugins/ml/public/application/overview/components/analytics_panel/analytics_panel.tsx index b2eda12abc578c..c379cd702daee0 100644 --- a/x-pack/plugins/ml/public/application/overview/components/analytics_panel/analytics_panel.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/analytics_panel/analytics_panel.tsx @@ -82,14 +82,14 @@ export const AnalyticsPanel: FC = ({ jobCreationDisabled }) => { title={

{i18n.translate('xpack.ml.overview.analyticsList.createFirstJobMessage', { - defaultMessage: 'Create your first analytics job', + defaultMessage: 'Create your first data frame analytics job', })}

} body={

{i18n.translate('xpack.ml.overview.analyticsList.emptyPromptText', { - defaultMessage: `Data frame analytics enable you to perform different analyses of your data and annotate it with the results. The analytics job stores the annotated data, as well as a copy of the source data, in a new index.`, + defaultMessage: `Data frame analytics enable you to perform different analyses of your data and annotates it with the results. The job puts the annotated data and a copy of the source data in a new index.`, })}

} diff --git a/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx b/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx index 5f5c3f7c28670a..dac39b1a2071da 100644 --- a/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx @@ -172,7 +172,7 @@ export const AnomalyDetectionPanel: FC = ({ jobCreationDisabled }) => {

{i18n.translate('xpack.ml.overview.anomalyDetection.emptyPromptText', { - defaultMessage: `Machine learning makes it easy to detect anomalies in time series data stored in Elasticsearch. Track one metric from a single machine or hundreds of metrics across thousands of machines. Start automatically spotting the anomalies hiding in your data and resolve issues faster.`, + defaultMessage: `Anomaly detection enables you to find unusual behavior in time series data. Start automatically spotting the anomalies hiding in your data and resolve issues faster.`, })}

diff --git a/x-pack/plugins/ml/public/application/overview/components/sidebar.tsx b/x-pack/plugins/ml/public/application/overview/components/sidebar.tsx index 219c195bab111e..3e4e9cfbd2b663 100644 --- a/x-pack/plugins/ml/public/application/overview/components/sidebar.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/sidebar.tsx @@ -11,7 +11,6 @@ import { useMlKibana } from '../../contexts/kibana'; const createJobLink = '#/jobs/new_job/step/index_or_search'; const feedbackLink = 'https://www.elastic.co/community/'; -const whatIsMachineLearningLink = 'https://www.elastic.co/what-is/elasticsearch-machine-learning'; interface Props { createAnomalyDetectionJobDisabled: boolean; @@ -60,7 +59,7 @@ export const OverviewSideBar: FC = ({ createAnomalyDetectionJobDisabled }

@@ -79,14 +78,6 @@ export const OverviewSideBar: FC = ({ createAnomalyDetectionJobDisabled } /> ), - whatIsMachineLearning: ( - - - - ), }} />

@@ -96,7 +87,7 @@ export const OverviewSideBar: FC = ({ createAnomalyDetectionJobDisabled }

diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index fd986ca0851d6f..8974f0b5b4d582 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10505,10 +10505,9 @@ "xpack.ml.overview.feedbackSectionTitle": "フィードバック", "xpack.ml.overview.gettingStartedSectionCreateJob": "新規ジョブを作成中", "xpack.ml.overview.gettingStartedSectionDocs": "ドキュメンテーション", - "xpack.ml.overview.gettingStartedSectionText": "機械学習へようこそ。はじめに{docs}や{createJob}をご参照ください。Elastic Stackの機械学習の詳細については、{whatIsMachineLearning}をご覧ください。{transforms}を使用して、分析ジョブの機能インデックスを作成することをお勧めします。", + "xpack.ml.overview.gettingStartedSectionText": "機械学習へようこそ。はじめに{docs}や{createJob}をご参照ください。{transforms}を使用して、分析ジョブの機能インデックスを作成することをお勧めします。", "xpack.ml.overview.gettingStartedSectionTitle": "はじめて使う", "xpack.ml.overview.gettingStartedSectionTransforms": "Elasticsearchの変換", - "xpack.ml.overview.gettingStartedSectionWhatIsMachineLearning": "こちら", "xpack.ml.overview.overviewLabel": "概要", "xpack.ml.overview.statsBar.failedAnalyticsLabel": "失敗", "xpack.ml.overview.statsBar.runningAnalyticsLabel": "実行中", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 162251f20c5c01..d36a62f15aee9e 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10508,10 +10508,9 @@ "xpack.ml.overview.feedbackSectionTitle": "反馈", "xpack.ml.overview.gettingStartedSectionCreateJob": "创建新作业", "xpack.ml.overview.gettingStartedSectionDocs": "文档", - "xpack.ml.overview.gettingStartedSectionText": "欢迎使用 Machine Learning。首先阅读我们的{docs}或{createJob}。有关 Elastic Stack 中的机器学习的详情,请参阅{whatIsMachineLearning}。建议使用 {transforms}为分析作业创建功能索引。", + "xpack.ml.overview.gettingStartedSectionText": "欢迎使用 Machine Learning。首先阅读我们的{docs}或{createJob}。建议使用 {transforms}为分析作业创建功能索引。", "xpack.ml.overview.gettingStartedSectionTitle": "入门", "xpack.ml.overview.gettingStartedSectionTransforms": "Elasticsearch 的转换", - "xpack.ml.overview.gettingStartedSectionWhatIsMachineLearning": "此处", "xpack.ml.overview.overviewLabel": "概览", "xpack.ml.overview.statsBar.failedAnalyticsLabel": "失败", "xpack.ml.overview.statsBar.runningAnalyticsLabel": "正在运行", From da4c33b022096b7d72930acea7ee1ce49d5230bc Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 29 Apr 2020 14:47:45 +0200 Subject: [PATCH 07/26] [Lens] Don't use auto interval to get interval for single bar (#64502) * feat: don't use auto interval to get interval for single bar * fix: fixing non auto intervals Co-authored-by: Elastic Machine --- .../lens/public/xy_visualization/index.ts | 1 + .../xy_visualization/xy_expression.test.tsx | 32 +++++++++++++++++-- .../public/xy_visualization/xy_expression.tsx | 25 +++++++++++---- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/index.ts b/x-pack/plugins/lens/public/xy_visualization/index.ts index 5dfae097be8345..3a280fb045b060 100644 --- a/x-pack/plugins/lens/public/xy_visualization/index.ts +++ b/x-pack/plugins/lens/public/xy_visualization/index.ts @@ -53,6 +53,7 @@ export class XyVisualization { ? EUI_CHARTS_THEME_DARK.theme : EUI_CHARTS_THEME_LIGHT.theme, timeZone: getTimeZone(core.uiSettings), + histogramBarTarget: core.uiSettings.get('histogram:barTarget'), }) ); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx index e75e5fe763d6ae..8db00aba0e36d3 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.test.tsx @@ -40,7 +40,7 @@ const createSampleDatatableWithRows = (rows: KibanaDatatableRow[]): KibanaDatata id: 'c', name: 'c', formatHint: { id: 'string' }, - meta: { type: 'date-histogram', aggConfigParams: { interval: '10s' } }, + meta: { type: 'date-histogram', aggConfigParams: { interval: 'auto' } }, }, { id: 'd', name: 'ColD', formatHint: { id: 'string' } }, ], @@ -156,6 +156,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -203,6 +204,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -237,15 +239,17 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); + // real auto interval is 30mins = 1800000 expect(component.find(Settings).prop('xDomain')).toMatchInlineSnapshot(` Object { "max": 1546491600000, "min": 1546405200000, - "minInterval": 10000, + "minInterval": 1728000, } `); }); @@ -271,6 +275,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -279,7 +284,7 @@ describe('xy_expression', () => { Object { "max": 1546491600000, "min": 1546405200000, - "minInterval": 10000, + "minInterval": 1728000, } `); }); @@ -307,6 +312,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -350,6 +356,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -383,6 +390,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -398,6 +406,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -414,6 +423,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -430,6 +440,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -472,6 +483,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -510,6 +522,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -527,6 +540,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -547,6 +561,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -565,6 +580,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="CEST" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -582,6 +598,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -606,6 +623,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -624,6 +642,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -684,6 +703,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -878,6 +898,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -894,6 +915,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -910,6 +932,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -927,6 +950,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); @@ -943,6 +967,7 @@ describe('xy_expression', () => { args={{ ...args, layers: [{ ...args.layers[0], accessors: ['a'] }] }} formatFactory={getFormatSpy} chartTheme={{}} + histogramBarTarget={50} timeZone="UTC" executeTriggerActions={executeTriggerActions} /> @@ -963,6 +988,7 @@ describe('xy_expression', () => { formatFactory={getFormatSpy} timeZone="UTC" chartTheme={{}} + histogramBarTarget={50} executeTriggerActions={executeTriggerActions} /> ); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index d6b6de479acfb2..85cf5753befd79 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -6,6 +6,7 @@ import React, { useState, useEffect } from 'react'; import ReactDOM from 'react-dom'; +import moment from 'moment'; import { Chart, Settings, @@ -35,8 +36,8 @@ import { XYArgs, SeriesType, visualizationTypes } from './types'; import { VisualizationContainer } from '../visualization_container'; import { isHorizontalChart } from './state_helpers'; import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; -import { parseInterval } from '../../../../../src/plugins/data/common'; import { getExecuteTriggerActions } from './services'; +import { parseInterval } from '../../../../../src/plugins/data/common'; type InferPropType = T extends React.FunctionComponent ? P : T; type SeriesSpec = InferPropType & @@ -58,6 +59,7 @@ type XYChartRenderProps = XYChartProps & { chartTheme: PartialTheme; formatFactory: FormatFactory; timeZone: string; + histogramBarTarget: number; executeTriggerActions: UiActionsStart['executeTriggerActions']; }; @@ -110,6 +112,7 @@ export const xyChart: ExpressionFunctionDefinition< export const getXyChartRenderer = (dependencies: { formatFactory: Promise; chartTheme: PartialTheme; + histogramBarTarget: number; timeZone: string; }): ExpressionRenderDefinition => ({ name: 'lens_xy_chart_renderer', @@ -130,6 +133,7 @@ export const getXyChartRenderer = (dependencies: { formatFactory={formatFactory} chartTheme={dependencies.chartTheme} timeZone={dependencies.timeZone} + histogramBarTarget={dependencies.histogramBarTarget} executeTriggerActions={executeTriggerActions} /> , @@ -169,6 +173,7 @@ export function XYChart({ formatFactory, timeZone, chartTheme, + histogramBarTarget, executeTriggerActions, }: XYChartRenderProps) { const { legend, layers } = args; @@ -212,18 +217,26 @@ export function XYChart({ const xTitle = (xAxisColumn && xAxisColumn.name) || args.xTitle; - // add minInterval only for single row value as it cannot be determined from dataset + function calculateMinInterval() { + // add minInterval only for single row value as it cannot be determined from dataset + if (data.dateRange && layers.every(layer => data.tables[layer.layerId].rows.length <= 1)) { + if (xAxisColumn?.meta?.aggConfigParams?.interval !== 'auto') + return parseInterval(xAxisColumn?.meta?.aggConfigParams?.interval)?.asMilliseconds(); - const minInterval = layers.every(layer => data.tables[layer.layerId].rows.length <= 1) - ? parseInterval(xAxisColumn?.meta?.aggConfigParams?.interval)?.asMilliseconds() - : undefined; + const { fromDate, toDate } = data.dateRange; + const duration = moment(toDate).diff(moment(fromDate)); + const targetMs = duration / histogramBarTarget; + return isNaN(targetMs) ? 0 : Math.max(Math.floor(targetMs), 1); + } + return undefined; + } const xDomain = data.dateRange && layers.every(l => l.xScaleType === 'time') ? { min: data.dateRange.fromDate.getTime(), max: data.dateRange.toDate.getTime(), - minInterval, + minInterval: calculateMinInterval(), } : undefined; return ( From f1d72ad1274d0a442747ae450dc08380769d8000 Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Wed, 29 Apr 2020 08:52:33 -0400 Subject: [PATCH 08/26] Expose security license on setup (#64651) --- x-pack/legacy/plugins/security/index.ts | 4 +-- x-pack/plugins/security/server/mocks.ts | 2 ++ x-pack/plugins/security/server/plugin.test.ts | 30 +++++++++---------- x-pack/plugins/security/server/plugin.ts | 6 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/x-pack/legacy/plugins/security/index.ts b/x-pack/legacy/plugins/security/index.ts index 5b2218af1fd521..b1dec2ce82c520 100644 --- a/x-pack/legacy/plugins/security/index.ts +++ b/x-pack/legacy/plugins/security/index.ts @@ -78,9 +78,7 @@ export const security = (kibana: Record) => // features are up to date. xpackInfo .feature(this.id) - .registerLicenseCheckResultsGenerator(() => - securityPlugin.__legacyCompat.license.getFeatures() - ); + .registerLicenseCheckResultsGenerator(() => securityPlugin.license.getFeatures()); server.expose({ getUser: async (request: LegacyRequest) => diff --git a/x-pack/plugins/security/server/mocks.ts b/x-pack/plugins/security/server/mocks.ts index ababf12c2be606..a6407366bbd3b2 100644 --- a/x-pack/plugins/security/server/mocks.ts +++ b/x-pack/plugins/security/server/mocks.ts @@ -8,6 +8,7 @@ import { SecurityPluginSetup } from './plugin'; import { authenticationMock } from './authentication/index.mock'; import { authorizationMock } from './authorization/index.mock'; +import { licenseMock } from '../common/licensing/index.mock'; function createSetupMock() { const mockAuthz = authorizationMock.create(); @@ -19,6 +20,7 @@ function createSetupMock() { mode: mockAuthz.mode, }, registerSpacesService: jest.fn(), + license: licenseMock.create(), __legacyCompat: {} as SecurityPluginSetup['__legacyCompat'], }; } diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts index 22a30f03c646a1..d58c999ddccdf8 100644 --- a/x-pack/plugins/security/server/plugin.test.ts +++ b/x-pack/plugins/security/server/plugin.test.ts @@ -50,21 +50,6 @@ describe('Security Plugin', () => { await expect(plugin.setup(mockCoreSetup, mockDependencies)).resolves.toMatchInlineSnapshot(` Object { "__legacyCompat": Object { - "license": Object { - "features$": Observable { - "_isScalar": false, - "operator": MapOperator { - "project": [Function], - "thisArg": undefined, - }, - "source": Observable { - "_isScalar": false, - "_subscribe": [Function], - }, - }, - "getFeatures": [Function], - "isEnabled": [Function], - }, "registerLegacyAPI": [Function], "registerPrivilegesWithCluster": [Function], }, @@ -103,6 +88,21 @@ describe('Security Plugin', () => { "useRbacForRequest": [Function], }, }, + "license": Object { + "features$": Observable { + "_isScalar": false, + "operator": MapOperator { + "project": [Function], + "thisArg": undefined, + }, + "source": Observable { + "_isScalar": false, + "_subscribe": [Function], + }, + }, + "getFeatures": [Function], + "isEnabled": [Function], + }, "registerSpacesService": [Function], } `); diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index e30b0caf76ddc0..97f5aea888dc7c 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -59,6 +59,7 @@ export interface SecurityPluginSetup { | 'invalidateAPIKeyAsInternalUser' >; authz: Pick; + license: SecurityLicense; /** * If Spaces plugin is available it's supposed to register its SpacesService with Security plugin @@ -73,7 +74,6 @@ export interface SecurityPluginSetup { __legacyCompat: { registerLegacyAPI: (legacyAPI: LegacyAPI) => void; registerPrivilegesWithCluster: () => void; - license: SecurityLicense; }; } @@ -194,6 +194,8 @@ export class Plugin { mode: authz.mode, }, + license, + registerSpacesService: service => { if (this.wasSpacesServiceAccessed()) { throw new Error('Spaces service has been accessed before registration.'); @@ -206,8 +208,6 @@ export class Plugin { registerLegacyAPI: (legacyAPI: LegacyAPI) => (this.legacyAPI = legacyAPI), registerPrivilegesWithCluster: async () => await authz.registerPrivilegesWithCluster(), - - license, }, }); } From 2c7741bba335aa3d91fc073ac88cfebc57263efb Mon Sep 17 00:00:00 2001 From: Sonja Krause-Harder Date: Wed, 29 Apr 2020 15:36:39 +0200 Subject: [PATCH 09/26] [EPM] Handle object type fields with properties in mappings (#64745) * Generate correct mapping for object type field with properties * Add test for fields definition in reverse order --- .../elasticsearch/template/template.test.ts | 50 +++++++++++++++++++ .../server/services/epm/fields/field.test.ts | 31 ++++++++++++ .../server/services/epm/fields/field.ts | 10 +++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts index 1a73c9581a2de7..3679c577ee5713 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts @@ -259,3 +259,53 @@ test('tests processing object field with dynamic set to strict', () => { const mappings = generateMappings(processedFields); expect(JSON.stringify(mappings)).toEqual(JSON.stringify(objectFieldDynamicStrictMapping)); }); + +test('tests processing object field with property', () => { + const objectFieldWithPropertyLiteralYml = ` +- name: a + type: object +- name: a.b + type: keyword + `; + const objectFieldWithPropertyMapping = { + properties: { + a: { + properties: { + b: { + ignore_above: 1024, + type: 'keyword', + }, + }, + }, + }, + }; + const fields: Field[] = safeLoad(objectFieldWithPropertyLiteralYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields); + expect(JSON.stringify(mappings)).toEqual(JSON.stringify(objectFieldWithPropertyMapping)); +}); + +test('tests processing object field with property, reverse order', () => { + const objectFieldWithPropertyReversedLiteralYml = ` +- name: a.b + type: keyword +- name: a + type: object + `; + const objectFieldWithPropertyReversedMapping = { + properties: { + a: { + properties: { + b: { + ignore_above: 1024, + type: 'keyword', + }, + }, + }, + }, + }; + const fields: Field[] = safeLoad(objectFieldWithPropertyReversedLiteralYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields); + expect(JSON.stringify(mappings)).toEqual(JSON.stringify(objectFieldWithPropertyReversedMapping)); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/fields/field.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/fields/field.test.ts index e3aef6077dbc30..42989bb1e3ac91 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/fields/field.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/fields/field.test.ts @@ -179,4 +179,35 @@ describe('processFields', () => { JSON.stringify(mixedFieldsExpanded) ); }); + + const objectFieldWithProperty = [ + { + name: 'a', + type: 'object', + dynamic: true, + }, + { + name: 'a.b', + type: 'keyword', + }, + ]; + + const objectFieldWithPropertyExpanded = [ + { + name: 'a', + type: 'group', + dynamic: true, + fields: [ + { + name: 'b', + type: 'keyword', + }, + ], + }, + ]; + test('correctly handles properties of object type fields', () => { + expect(JSON.stringify(processFields(objectFieldWithProperty))).toEqual( + JSON.stringify(objectFieldWithPropertyExpanded) + ); + }); }); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/fields/field.ts b/x-pack/plugins/ingest_manager/server/services/epm/fields/field.ts index 9c9843e0454ab5..edf7624d3f0d5b 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/fields/field.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/fields/field.ts @@ -108,7 +108,15 @@ function dedupFields(fields: Fields): Fields { return f.name === field.name; }); if (found) { - if (found.type === 'group' && field.type === 'group' && found.fields && field.fields) { + if ( + (found.type === 'group' || found.type === 'object') && + field.type === 'group' && + field.fields + ) { + if (!found.fields) { + found.fields = []; + } + found.type = 'group'; found.fields = dedupFields(found.fields.concat(field.fields)); } else { // only 'group' fields can be merged in this way From ac61783a2d70b3a6c7184a1a6591ec74ddb9ffbc Mon Sep 17 00:00:00 2001 From: Corey Robertson Date: Wed, 29 Apr 2020 09:49:25 -0400 Subject: [PATCH 10/26] [CANVAS] Adds Canvas Platform Service (#64453) * Adds Canvas Platform Service * Fix type check Co-authored-by: Elastic Machine --- .../components/app/track_route_change.js | 18 ++++++++----- x-pack/legacy/plugins/canvas/public/legacy.ts | 2 -- .../plugins/canvas/public/lib/breadcrumbs.ts | 4 +-- .../public/lib/custom_element_service.ts | 4 +-- .../canvas/public/lib/documentation_links.ts | 10 +++---- .../plugins/canvas/public/lib/es_service.ts | 8 +++--- .../canvas/public/lib/workpad_service.js | 8 +++--- .../legacy/plugins/canvas/public/plugin.tsx | 19 +++++++++++--- .../plugins/canvas/public/services/index.ts | 4 ++- .../canvas/public/services/platform.ts | 24 +++++++++++++++++ .../canvas/public/state/initial_state.js | 4 +-- .../canvas/public/state/reducers/workpad.js | 26 +++++++++++-------- 12 files changed, 88 insertions(+), 43 deletions(-) create mode 100644 x-pack/legacy/plugins/canvas/public/services/platform.ts diff --git a/x-pack/legacy/plugins/canvas/public/components/app/track_route_change.js b/x-pack/legacy/plugins/canvas/public/components/app/track_route_change.js index e837f5200a1590..2886aa868eb9e1 100644 --- a/x-pack/legacy/plugins/canvas/public/components/app/track_route_change.js +++ b/x-pack/legacy/plugins/canvas/public/components/app/track_route_change.js @@ -7,13 +7,17 @@ import { get } from 'lodash'; import { getWindow } from '../../lib/get_window'; import { CANVAS_APP } from '../../../common/lib/constants'; -import { getCoreStart, getStartPlugins } from '../../legacy'; +import { platformService } from '../../services'; export function trackRouteChange() { - const basePath = getCoreStart().http.basePath.get(); - // storage.set(LOCALSTORAGE_LASTPAGE, pathname); - getStartPlugins().__LEGACY.trackSubUrlForApp( - CANVAS_APP, - getStartPlugins().__LEGACY.absoluteToParsedUrl(get(getWindow(), 'location.href'), basePath) - ); + const basePath = platformService.getService().coreStart.http.basePath.get(); + + platformService + .getService() + .startPlugins.__LEGACY.trackSubUrlForApp( + CANVAS_APP, + platformService + .getService() + .startPlugins.__LEGACY.absoluteToParsedUrl(get(getWindow(), 'location.href'), basePath) + ); } diff --git a/x-pack/legacy/plugins/canvas/public/legacy.ts b/x-pack/legacy/plugins/canvas/public/legacy.ts index 5bb628909c32e2..f83887bbcbdfd3 100644 --- a/x-pack/legacy/plugins/canvas/public/legacy.ts +++ b/x-pack/legacy/plugins/canvas/public/legacy.ts @@ -35,8 +35,6 @@ const shimStartPlugins: CanvasStartDeps = { __LEGACY: { // ToDo: Copy directly into canvas absoluteToParsedUrl, - // ToDo: Copy directly into canvas - formatMsg, // ToDo: Won't be a part of New Platform. Will need to handle internally trackSubUrlForApp: chrome.trackSubUrlForApp, }, diff --git a/x-pack/legacy/plugins/canvas/public/lib/breadcrumbs.ts b/x-pack/legacy/plugins/canvas/public/lib/breadcrumbs.ts index 834d5868c35ea7..57b513affd7815 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/breadcrumbs.ts +++ b/x-pack/legacy/plugins/canvas/public/lib/breadcrumbs.ts @@ -5,7 +5,7 @@ */ import { ChromeBreadcrumb } from '../../../../../../src/core/public'; -import { getCoreStart } from '../legacy'; +import { platformService } from '../services'; export const getBaseBreadcrumb = () => ({ text: 'Canvas', @@ -24,6 +24,6 @@ export const getWorkpadBreadcrumb = ({ }; export const setBreadcrumb = (paths: ChromeBreadcrumb | ChromeBreadcrumb[]) => { - const setBreadCrumbs = getCoreStart().chrome.setBreadcrumbs; + const setBreadCrumbs = platformService.getService().coreStart.chrome.setBreadcrumbs; setBreadCrumbs(Array.isArray(paths) ? paths : [paths]); }; diff --git a/x-pack/legacy/plugins/canvas/public/lib/custom_element_service.ts b/x-pack/legacy/plugins/canvas/public/lib/custom_element_service.ts index 4118bb81b83639..8952802dc2f2be 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/custom_element_service.ts +++ b/x-pack/legacy/plugins/canvas/public/lib/custom_element_service.ts @@ -8,10 +8,10 @@ import { AxiosPromise } from 'axios'; import { API_ROUTE_CUSTOM_ELEMENT } from '../../common/lib/constants'; import { fetch } from '../../common/lib/fetch'; import { CustomElement } from '../../types'; -import { getCoreStart } from '../legacy'; +import { platformService } from '../services'; const getApiPath = function() { - const basePath = getCoreStart().http.basePath.get(); + const basePath = platformService.getService().coreStart.http.basePath.get(); return `${basePath}${API_ROUTE_CUSTOM_ELEMENT}`; }; diff --git a/x-pack/legacy/plugins/canvas/public/lib/documentation_links.ts b/x-pack/legacy/plugins/canvas/public/lib/documentation_links.ts index 40e09ee39d7144..6430f7d87d4f76 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/documentation_links.ts +++ b/x-pack/legacy/plugins/canvas/public/lib/documentation_links.ts @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getCoreStart } from '../legacy'; +import { platformService } from '../services'; export const getDocumentationLinks = () => ({ - canvas: `${getCoreStart().docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${ - getCoreStart().docLinks.DOC_LINK_VERSION + canvas: `${platformService.getService().coreStart.docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${ + platformService.getService().coreStart.docLinks.DOC_LINK_VERSION }/canvas.html`, - numeral: `${getCoreStart().docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${ - getCoreStart().docLinks.DOC_LINK_VERSION + numeral: `${platformService.getService().coreStart.docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${ + platformService.getService().coreStart.docLinks.DOC_LINK_VERSION }/guide/numeral.html`, }); diff --git a/x-pack/legacy/plugins/canvas/public/lib/es_service.ts b/x-pack/legacy/plugins/canvas/public/lib/es_service.ts index 6aa4968f29155d..184f4f3c8af7c3 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/es_service.ts +++ b/x-pack/legacy/plugins/canvas/public/lib/es_service.ts @@ -11,21 +11,21 @@ import { API_ROUTE } from '../../common/lib/constants'; import { fetch } from '../../common/lib/fetch'; import { ErrorStrings } from '../../i18n'; import { notifyService } from '../services'; -import { getCoreStart } from '../legacy'; +import { platformService } from '../services'; const { esService: strings } = ErrorStrings; const getApiPath = function() { - const basePath = getCoreStart().http.basePath.get(); + const basePath = platformService.getService().coreStart.http.basePath.get(); return basePath + API_ROUTE; }; const getSavedObjectsClient = function() { - return getCoreStart().savedObjects.client; + return platformService.getService().coreStart.savedObjects.client; }; const getAdvancedSettings = function() { - return getCoreStart().uiSettings; + return platformService.getService().coreStart.uiSettings; }; export const getFields = (index = '_all') => { diff --git a/x-pack/legacy/plugins/canvas/public/lib/workpad_service.js b/x-pack/legacy/plugins/canvas/public/lib/workpad_service.js index f3681f50c56a59..e6628399f53c22 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/workpad_service.js +++ b/x-pack/legacy/plugins/canvas/public/lib/workpad_service.js @@ -11,7 +11,7 @@ import { DEFAULT_WORKPAD_CSS, } from '../../common/lib/constants'; import { fetch } from '../../common/lib/fetch'; -import { getCoreStart } from '../legacy'; +import { platformService } from '../services'; /* Remove any top level keys from the workpad which will be rejected by validation */ @@ -43,17 +43,17 @@ const sanitizeWorkpad = function(workpad) { }; const getApiPath = function() { - const basePath = getCoreStart().http.basePath.get(); + const basePath = platformService.getService().coreStart.http.basePath.get(); return `${basePath}${API_ROUTE_WORKPAD}`; }; const getApiPathStructures = function() { - const basePath = getCoreStart().http.basePath.get(); + const basePath = platformService.getService().coreStart.http.basePath.get(); return `${basePath}${API_ROUTE_WORKPAD_STRUCTURES}`; }; const getApiPathAssets = function() { - const basePath = getCoreStart().http.basePath.get(); + const basePath = platformService.getService().coreStart.http.basePath.get(); return `${basePath}${API_ROUTE_WORKPAD_ASSETS}`; }; diff --git a/x-pack/legacy/plugins/canvas/public/plugin.tsx b/x-pack/legacy/plugins/canvas/public/plugin.tsx index 36ce1974be2724..baeb4ebd453d2c 100644 --- a/x-pack/legacy/plugins/canvas/public/plugin.tsx +++ b/x-pack/legacy/plugins/canvas/public/plugin.tsx @@ -44,7 +44,6 @@ export interface CanvasStartDeps { uiActions: UiActionsStart; __LEGACY: { absoluteToParsedUrl: (url: string, basePath: string) => any; - formatMsg: any; trackSubUrlForApp: Chrome['trackSubUrlForApp']; }; } @@ -64,6 +63,7 @@ export class CanvasPlugin implements Plugin { // TODO: Do we want to completely move canvas_plugin_src into it's own plugin? private srcPlugin = new CanvasSrcPlugin(); + private startPlugins: CanvasStartDeps | undefined; public setup(core: CoreSetup, plugins: CanvasSetupDeps) { const { api: canvasApi, registries } = getPluginApi(plugins.expressions); @@ -73,14 +73,26 @@ export class CanvasPlugin core.application.register({ id: 'canvas', title: 'Canvas App', - async mount(context, params) { + mount: async (context, params) => { // Load application bundle const { renderApp, initializeCanvas, teardownCanvas } = await import('./application'); // Get start services const [coreStart, depsStart] = await core.getStartServices(); - const canvasStore = await initializeCanvas(core, coreStart, plugins, depsStart, registries); + // TODO: We only need this to get the __LEGACY stuff that isn't coming from getStartSevices. + // We won't need this as soon as we move over to NP Completely + if (!this.startPlugins) { + throw new Error('Start Plugins not ready at mount time'); + } + + const canvasStore = await initializeCanvas( + core, + coreStart, + plugins, + this.startPlugins, + registries + ); const unmount = renderApp(coreStart, depsStart, params, canvasStore); @@ -115,6 +127,7 @@ export class CanvasPlugin } public start(core: CoreStart, plugins: CanvasStartDeps) { + this.startPlugins = plugins; this.srcPlugin.start(core, plugins); initLoadingIndicator(core.http.addLoadingCountSource); } diff --git a/x-pack/legacy/plugins/canvas/public/services/index.ts b/x-pack/legacy/plugins/canvas/public/services/index.ts index 12c0a687bf308b..17d836f1441c96 100644 --- a/x-pack/legacy/plugins/canvas/public/services/index.ts +++ b/x-pack/legacy/plugins/canvas/public/services/index.ts @@ -7,6 +7,7 @@ import { CoreSetup, CoreStart } from '../../../../../../src/core/public'; import { CanvasSetupDeps, CanvasStartDeps } from '../plugin'; import { notifyServiceFactory } from './notify'; +import { platformServiceFactory } from './platform'; export type CanvasServiceFactory = ( coreSetup: CoreSetup, @@ -49,6 +50,7 @@ export type ServiceFromProvider

= P extends CanvasServiceProvider ? export const services = { notify: new CanvasServiceProvider(notifyServiceFactory), + platform: new CanvasServiceProvider(platformServiceFactory), }; export interface CanvasServices { @@ -70,4 +72,4 @@ export const stopServices = () => { Object.entries(services).forEach(([key, provider]) => provider.stop()); }; -export const { notify: notifyService } = services; +export const { notify: notifyService, platform: platformService } = services; diff --git a/x-pack/legacy/plugins/canvas/public/services/platform.ts b/x-pack/legacy/plugins/canvas/public/services/platform.ts new file mode 100644 index 00000000000000..440e9523044c1c --- /dev/null +++ b/x-pack/legacy/plugins/canvas/public/services/platform.ts @@ -0,0 +1,24 @@ +/* + * 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 { CanvasServiceFactory } from '.'; +import { CoreStart, CoreSetup, CanvasSetupDeps, CanvasStartDeps } from '../plugin'; + +interface PlatformService { + coreSetup: CoreSetup; + coreStart: CoreStart; + setupPlugins: CanvasSetupDeps; + startPlugins: CanvasStartDeps; +} + +export const platformServiceFactory: CanvasServiceFactory = ( + coreSetup, + coreStart, + setupPlugins, + startPlugins +) => { + return { coreSetup, coreStart, setupPlugins, startPlugins }; +}; diff --git a/x-pack/legacy/plugins/canvas/public/state/initial_state.js b/x-pack/legacy/plugins/canvas/public/state/initial_state.js index 40c017543147fc..bfa68b33908e01 100644 --- a/x-pack/legacy/plugins/canvas/public/state/initial_state.js +++ b/x-pack/legacy/plugins/canvas/public/state/initial_state.js @@ -5,7 +5,7 @@ */ import { get } from 'lodash'; -import { getCoreStart } from '../legacy'; +import { platformService } from '../services'; import { getDefaultWorkpad } from './defaults'; export const getInitialState = path => { @@ -13,7 +13,7 @@ export const getInitialState = path => { app: {}, // Kibana stuff in here assets: {}, // assets end up here transient: { - canUserWrite: getCoreStart().application.capabilities.canvas.save, + canUserWrite: platformService.getService().coreStart.application.capabilities.canvas.save, zoomScale: 1, elementStats: { total: 0, diff --git a/x-pack/legacy/plugins/canvas/public/state/reducers/workpad.js b/x-pack/legacy/plugins/canvas/public/state/reducers/workpad.js index 12733680ed32d4..30f9c638a054fe 100644 --- a/x-pack/legacy/plugins/canvas/public/state/reducers/workpad.js +++ b/x-pack/legacy/plugins/canvas/public/state/reducers/workpad.js @@ -5,7 +5,7 @@ */ import { handleActions } from 'redux-actions'; -import { getCoreStart } from '../../legacy'; +import { platformService } from '../../services'; import { getDefaultWorkpad } from '../defaults'; import { setWorkpad, @@ -22,11 +22,13 @@ import { APP_ROUTE_WORKPAD } from '../../../common/lib/constants'; export const workpadReducer = handleActions( { [setWorkpad]: (workpadState, { payload }) => { - getCoreStart().chrome.recentlyAccessed.add( - `${APP_ROUTE_WORKPAD}/${payload.id}`, - payload.name, - payload.id - ); + platformService + .getService() + .coreStart.chrome.recentlyAccessed.add( + `${APP_ROUTE_WORKPAD}/${payload.id}`, + payload.name, + payload.id + ); return payload; }, @@ -39,11 +41,13 @@ export const workpadReducer = handleActions( }, [setName]: (workpadState, { payload }) => { - getCoreStart().chrome.recentlyAccessed.add( - `${APP_ROUTE_WORKPAD}/${workpadState.id}`, - payload, - workpadState.id - ); + platformService + .getService() + .coreStart.chrome.recentlyAccessed.add( + `${APP_ROUTE_WORKPAD}/${workpadState.id}`, + payload, + workpadState.id + ); return { ...workpadState, name: payload }; }, From 30e41c5d8f9ebf9fcc5dade55d277314b7aee1ee Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Wed, 29 Apr 2020 08:25:12 -0600 Subject: [PATCH 11/26] Update codeowners for endpoint and siem ## Summary * Update codeowners for endpoint and SIEM * Remove legacy stuff --- .github/CODEOWNERS | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cee2f32c2cb9e6..9e74daa13513d9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -208,22 +208,21 @@ /x-pack/plugins/watcher/ @elastic/es-ui # Endpoint -/x-pack/plugins/endpoint/ @elastic/endpoint-app-team -/x-pack/test/api_integration/apis/endpoint/ @elastic/endpoint-app-team -/x-pack/test/endpoint_api_integration_no_ingest/ @elastic/endpoint-app-team -/x-pack/test/functional_endpoint/ @elastic/endpoint-app-team -/x-pack/test/functional_endpoint_ingest_failure/ @elastic/endpoint-app-team -/x-pack/test/functional/es_archives/endpoint/ @elastic/endpoint-app-team -/x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/endpoint-app-team -/x-pack/test/plugin_functional/test_suites/resolver/ @elastic/endpoint-app-team +/x-pack/plugins/endpoint/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/api_integration/apis/endpoint/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/endpoint_api_integration_no_ingest/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/functional_endpoint/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/functional_endpoint_ingest_failure/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/functional/es_archives/endpoint/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/plugin_functional/test_suites/resolver/ @elastic/endpoint-app-team @elastic/siem # SIEM -/x-pack/legacy/plugins/siem/ @elastic/siem -/x-pack/plugins/siem/ @elastic/siem -/x-pack/test/detection_engine_api_integration @elastic/siem -/x-pack/test/api_integration/apis/siem @elastic/siem -/x-pack/plugins/case @elastic/siem -/x-pack/plugins/lists @elastic/siem +/x-pack/plugins/siem/ @elastic/siem @elastic/endpoint-app-team +/x-pack/test/detection_engine_api_integration @elastic/siem @elastic/endpoint-app-team +/x-pack/test/api_integration/apis/siem @elastic/siem @elastic/endpoint-app-team +/x-pack/plugins/case @elastic/siem @elastic/endpoint-app-team +/x-pack/plugins/lists @elastic/siem @elastic/endpoint-app-team # Security Intelligence And Analytics /x-pack/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules @elastic/security-intelligence-analytics From 9fe722935738de887d8fa244d556cc41e55a38bd Mon Sep 17 00:00:00 2001 From: Gidi Meir Morris Date: Wed, 29 Apr 2020 15:46:54 +0100 Subject: [PATCH 12/26] [Alerting] migrates all remaining plugins to new platform (#64335) Completes the migration of all Alerting Services plugins onto the Kibana Platform It includes: 1. Actions plugin 2. Alerting plugin 3. Task Manager plugin 4. Triggers UI plugin And touches the Uptime and Siem plugins as their use of the Task Manager relied on some of the legacy lifecycle to work (registering AlertTypes and Telemetry tasks after the Start stage has already began). The fix was simply to moves these registrations to the Setup stage. --- .github/CODEOWNERS | 3 - x-pack/index.js | 6 - x-pack/legacy/plugins/actions/server/index.ts | 38 --- x-pack/legacy/plugins/alerting/index.ts | 7 - .../legacy/plugins/alerting/server/index.ts | 40 --- .../plugins/monitoring/common/constants.ts | 2 +- .../plugins/task_manager/server/index.ts | 22 +- .../plugins/triggers_actions_ui/index.ts | 34 --- .../triggers_actions_ui/public/index.scss | 2 - x-pack/plugins/actions/server/plugin.ts | 15 +- .../actions/server/saved_objects/index.ts | 42 +++ .../server/saved_objects}/mappings.json | 0 x-pack/plugins/alerting/server/plugin.ts | 13 +- .../alerting/server/saved_objects/index.ts | 33 +++ .../server/saved_objects}/mappings.json | 0 x-pack/plugins/monitoring/common/constants.ts | 2 +- .../scripts/get_action_instances.sh | 2 +- .../scripts/get_action_types.sh | 2 +- x-pack/plugins/task_manager/server/plugin.ts | 21 +- .../server/saved_objects/index.ts | 23 ++ .../server/saved_objects}/mappings.json | 0 .../server/saved_objects}/migrations.ts | 0 .../task_manager/server/task_manager.ts | 8 +- .../builtin_action_types/servicenow.ts | 2 +- .../actions/builtin_action_types/slack.ts | 2 +- .../actions/builtin_action_types/webhook.ts | 2 +- .../alerting_api_integration/common/config.ts | 5 +- .../common/fixtures/plugins/aad/index.ts | 2 +- .../{actions => actions_simulators}/README.md | 0 .../{actions => actions_simulators}/index.ts | 2 +- .../package.json | 0 .../pagerduty_simulation.ts | 0 .../servicenow_simulation.ts | 0 .../slack_simulation.ts | 0 .../webhook_simulation.ts | 0 .../common/fixtures/plugins/alerts/index.ts | 4 +- .../fixtures/plugins/task_manager/index.ts | 2 +- .../actions/builtin_action_types/pagerduty.ts | 2 +- .../builtin_action_types/servicenow.ts | 2 +- .../actions/builtin_action_types/slack.ts | 2 +- .../actions/builtin_action_types/webhook.ts | 2 +- .../actions/builtin_action_types/webhook.ts | 2 +- .../common/config.ts | 1 - x-pack/test/functional_with_es_ssl/config.ts | 2 - .../plugins/sample_task_plugin/kibana.json | 9 + .../plugins/sample_task_plugin/package.json | 18 ++ .../sample_task_plugin/server}/index.ts | 4 +- .../sample_task_plugin/server/init_routes.ts | 252 ++++++++++++++++++ .../sample_task_plugin/server/plugin.ts | 164 ++++++++++++ .../plugins/task_manager/index.js | 150 ----------- .../plugins/task_manager/init_routes.js | 236 ---------------- .../plugins/task_manager/package.json | 12 - .../task_manager/task_manager_integration.js | 21 +- 53 files changed, 587 insertions(+), 628 deletions(-) delete mode 100644 x-pack/legacy/plugins/actions/server/index.ts delete mode 100644 x-pack/legacy/plugins/alerting/index.ts delete mode 100644 x-pack/legacy/plugins/alerting/server/index.ts delete mode 100644 x-pack/legacy/plugins/triggers_actions_ui/index.ts delete mode 100644 x-pack/legacy/plugins/triggers_actions_ui/public/index.scss create mode 100644 x-pack/plugins/actions/server/saved_objects/index.ts rename x-pack/{legacy/plugins/actions/server => plugins/actions/server/saved_objects}/mappings.json (100%) create mode 100644 x-pack/plugins/alerting/server/saved_objects/index.ts rename x-pack/{legacy/plugins/alerting/server => plugins/alerting/server/saved_objects}/mappings.json (100%) create mode 100644 x-pack/plugins/task_manager/server/saved_objects/index.ts rename x-pack/{legacy/plugins/task_manager/server => plugins/task_manager/server/saved_objects}/mappings.json (100%) rename x-pack/{legacy/plugins/task_manager/server => plugins/task_manager/server/saved_objects}/migrations.ts (100%) rename x-pack/test/alerting_api_integration/common/fixtures/plugins/{actions => actions_simulators}/README.md (100%) rename x-pack/test/alerting_api_integration/common/fixtures/plugins/{actions => actions_simulators}/index.ts (98%) rename x-pack/test/alerting_api_integration/common/fixtures/plugins/{actions => actions_simulators}/package.json (100%) rename x-pack/test/alerting_api_integration/common/fixtures/plugins/{actions => actions_simulators}/pagerduty_simulation.ts (100%) rename x-pack/test/alerting_api_integration/common/fixtures/plugins/{actions => actions_simulators}/servicenow_simulation.ts (100%) rename x-pack/test/alerting_api_integration/common/fixtures/plugins/{actions => actions_simulators}/slack_simulation.ts (100%) rename x-pack/test/alerting_api_integration/common/fixtures/plugins/{actions => actions_simulators}/webhook_simulation.ts (100%) create mode 100644 x-pack/test/plugin_api_integration/plugins/sample_task_plugin/kibana.json create mode 100644 x-pack/test/plugin_api_integration/plugins/sample_task_plugin/package.json rename x-pack/{legacy/plugins/actions => test/plugin_api_integration/plugins/sample_task_plugin/server}/index.ts (65%) create mode 100644 x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts create mode 100644 x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/plugin.ts delete mode 100644 x-pack/test/plugin_api_integration/plugins/task_manager/index.js delete mode 100644 x-pack/test/plugin_api_integration/plugins/task_manager/init_routes.js delete mode 100644 x-pack/test/plugin_api_integration/plugins/task_manager/package.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9e74daa13513d9..a97400ee09c0e9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -166,8 +166,6 @@ /x-pack/plugins/telemetry_collection_xpack/ @elastic/pulse # Kibana Alerting Services -/x-pack/legacy/plugins/alerting/ @elastic/kibana-alerting-services -/x-pack/legacy/plugins/actions/ @elastic/kibana-alerting-services /x-pack/plugins/alerting/ @elastic/kibana-alerting-services /x-pack/plugins/actions/ @elastic/kibana-alerting-services /x-pack/plugins/event_log/ @elastic/kibana-alerting-services @@ -175,7 +173,6 @@ /x-pack/test/alerting_api_integration/ @elastic/kibana-alerting-services /x-pack/test/plugin_api_integration/plugins/task_manager/ @elastic/kibana-alerting-services /x-pack/test/plugin_api_integration/test_suites/task_manager/ @elastic/kibana-alerting-services -/x-pack/legacy/plugins/triggers_actions_ui/ @elastic/kibana-alerting-services /x-pack/plugins/triggers_actions_ui/ @elastic/kibana-alerting-services /x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/ @elastic/kibana-alerting-services /x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/ @elastic/kibana-alerting-services diff --git a/x-pack/index.js b/x-pack/index.js index a4142e24e4aeb6..cfadddac3994ac 100644 --- a/x-pack/index.js +++ b/x-pack/index.js @@ -17,10 +17,7 @@ import { canvas } from './legacy/plugins/canvas'; import { infra } from './legacy/plugins/infra'; import { taskManager } from './legacy/plugins/task_manager'; import { encryptedSavedObjects } from './legacy/plugins/encrypted_saved_objects'; -import { actions } from './legacy/plugins/actions'; -import { alerting } from './legacy/plugins/alerting'; import { ingestManager } from './legacy/plugins/ingest_manager'; -import { triggersActionsUI } from './legacy/plugins/triggers_actions_ui'; module.exports = function(kibana) { return [ @@ -37,9 +34,6 @@ module.exports = function(kibana) { infra(kibana), taskManager(kibana), encryptedSavedObjects(kibana), - actions(kibana), - alerting(kibana), ingestManager(kibana), - triggersActionsUI(kibana), ]; }; diff --git a/x-pack/legacy/plugins/actions/server/index.ts b/x-pack/legacy/plugins/actions/server/index.ts deleted file mode 100644 index 63dd6f99f9c24b..00000000000000 --- a/x-pack/legacy/plugins/actions/server/index.ts +++ /dev/null @@ -1,38 +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 { Root } from 'joi'; -import { Legacy } from 'kibana'; -import mappings from './mappings.json'; -import { - LegacyPluginApi, - LegacyPluginSpec, - ArrayOrItem, -} from '../../../../../src/legacy/plugin_discovery/types'; - -export function actions(kibana: LegacyPluginApi): ArrayOrItem { - return new kibana.Plugin({ - id: 'actions', - configPrefix: 'xpack.actions', - config(Joi: Root) { - return Joi.object({ - enabled: Joi.boolean().default(true), - }) - .unknown(true) - .default(); - }, - require: ['kibana', 'elasticsearch'], - isEnabled(config: Legacy.KibanaConfig) { - return ( - config.get('xpack.encryptedSavedObjects.enabled') === true && - config.get('xpack.actions.enabled') === true && - config.get('xpack.task_manager.enabled') === true - ); - }, - uiExports: { - mappings, - }, - } as Legacy.PluginSpecOptions); -} diff --git a/x-pack/legacy/plugins/alerting/index.ts b/x-pack/legacy/plugins/alerting/index.ts deleted file mode 100644 index 0d0a698841269f..00000000000000 --- a/x-pack/legacy/plugins/alerting/index.ts +++ /dev/null @@ -1,7 +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. - */ - -export * from './server'; diff --git a/x-pack/legacy/plugins/alerting/server/index.ts b/x-pack/legacy/plugins/alerting/server/index.ts deleted file mode 100644 index 065af7dedebd92..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/index.ts +++ /dev/null @@ -1,40 +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 { Legacy } from 'kibana'; -import { Root } from 'joi'; -import mappings from './mappings.json'; -import { - LegacyPluginApi, - LegacyPluginSpec, - ArrayOrItem, -} from '../../../../../src/legacy/plugin_discovery/types'; - -export function alerting(kibana: LegacyPluginApi): ArrayOrItem { - return new kibana.Plugin({ - id: 'alerting', - configPrefix: 'xpack.alerting', - require: ['kibana', 'elasticsearch', 'actions', 'task_manager', 'encryptedSavedObjects'], - isEnabled(config: Legacy.KibanaConfig) { - return ( - config.get('xpack.alerting.enabled') === true && - config.get('xpack.actions.enabled') === true && - config.get('xpack.encryptedSavedObjects.enabled') === true && - config.get('xpack.task_manager.enabled') === true - ); - }, - config(Joi: Root) { - return Joi.object() - .keys({ - enabled: Joi.boolean().default(true), - }) - .default(); - }, - uiExports: { - mappings, - }, - } as Legacy.PluginSpecOptions); -} diff --git a/x-pack/legacy/plugins/monitoring/common/constants.ts b/x-pack/legacy/plugins/monitoring/common/constants.ts index 3a4c7b71dcd03d..36030e1fa7f2a5 100644 --- a/x-pack/legacy/plugins/monitoring/common/constants.ts +++ b/x-pack/legacy/plugins/monitoring/common/constants.ts @@ -251,7 +251,7 @@ export const ALERT_TYPES = [ALERT_TYPE_LICENSE_EXPIRATION, ALERT_TYPE_CLUSTER_ST /** * Matches the id for the built-in in email action type - * See x-pack/legacy/plugins/actions/server/builtin_action_types/email.ts + * See x-pack/plugins/actions/server/builtin_action_types/email.ts */ export const ALERT_ACTION_TYPE_EMAIL = '.email'; diff --git a/x-pack/legacy/plugins/task_manager/server/index.ts b/x-pack/legacy/plugins/task_manager/server/index.ts index 3ea687f7003f40..a3167920efa06c 100644 --- a/x-pack/legacy/plugins/task_manager/server/index.ts +++ b/x-pack/legacy/plugins/task_manager/server/index.ts @@ -6,8 +6,6 @@ import { Root } from 'joi'; import { Legacy } from 'kibana'; -import mappings from './mappings.json'; -import { migrations } from './migrations'; import { createLegacyApi, getTaskManagerSetup } from './legacy'; export { LegacyTaskManagerApi, getTaskManagerSetup, getTaskManagerStart } from './legacy'; @@ -21,19 +19,6 @@ import { ArrayOrItem, } from '../../../../../src/legacy/plugin_discovery/types'; -const savedObjectSchemas = { - task: { - hidden: true, - isNamespaceAgnostic: true, - convertToAliasScript: `ctx._id = ctx._source.type + ':' + ctx._id`, - // legacy config is marked as any in core, no choice here - // eslint-disable-next-line @typescript-eslint/no-explicit-any - indexPattern(config: any) { - return config.get('xpack.task_manager.index'); - }, - }, -}; - export function taskManager(kibana: LegacyPluginApi): ArrayOrItem { return new kibana.Plugin({ id: 'task_manager', @@ -58,7 +43,7 @@ export function taskManager(kibana: LegacyPluginApi): ArrayOrItem { // we can't tell the Kibana Platform Task Manager plugin to // to wait to `start` as that happens before legacy plugins @@ -77,10 +62,5 @@ export function taskManager(kibana: LegacyPluginApi): ArrayOrItem, Plugi ); } - // Encrypted attributes - // - `secrets` properties will be encrypted - // - `config` will be included in AAD - // - everything else excluded from AAD - plugins.encryptedSavedObjects.registerType({ - type: 'action', - attributesToEncrypt: new Set(['secrets']), - attributesToExcludeFromAAD: new Set(['name']), - }); - plugins.encryptedSavedObjects.registerType({ - type: 'action_task_params', - attributesToEncrypt: new Set(['apiKey']), - }); + setupSavedObjects(core.savedObjects, plugins.encryptedSavedObjects); plugins.eventLog.registerProviderActions(EVENT_LOG_PROVIDER, Object.values(EVENT_LOG_ACTIONS)); this.eventLogger = plugins.eventLog.getLogger({ diff --git a/x-pack/plugins/actions/server/saved_objects/index.ts b/x-pack/plugins/actions/server/saved_objects/index.ts new file mode 100644 index 00000000000000..dbd7925f968713 --- /dev/null +++ b/x-pack/plugins/actions/server/saved_objects/index.ts @@ -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. + */ + +import { SavedObjectsServiceSetup } from 'kibana/server'; +import mappings from './mappings.json'; +import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server'; + +export function setupSavedObjects( + savedObjects: SavedObjectsServiceSetup, + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup +) { + savedObjects.registerType({ + name: 'action', + hidden: false, + namespaceType: 'single', + mappings: mappings.action, + }); + + // Encrypted attributes + // - `secrets` properties will be encrypted + // - `config` will be included in AAD + // - everything else excluded from AAD + encryptedSavedObjects.registerType({ + type: 'action', + attributesToEncrypt: new Set(['secrets']), + attributesToExcludeFromAAD: new Set(['name']), + }); + + savedObjects.registerType({ + name: 'action_task_params', + hidden: false, + namespaceType: 'single', + mappings: mappings.action_task_params, + }); + encryptedSavedObjects.registerType({ + type: 'action_task_params', + attributesToEncrypt: new Set(['apiKey']), + }); +} diff --git a/x-pack/legacy/plugins/actions/server/mappings.json b/x-pack/plugins/actions/server/saved_objects/mappings.json similarity index 100% rename from x-pack/legacy/plugins/actions/server/mappings.json rename to x-pack/plugins/actions/server/saved_objects/mappings.json diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index c03d3506a051d4..8cdde2eeb9877a 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -58,6 +58,7 @@ import { Services } from './types'; import { registerAlertsUsageCollector } from './usage'; import { initializeAlertingTelemetry, scheduleAlertingTelemetry } from './usage/task'; import { IEventLogger, IEventLogService } from '../../event_log/server'; +import { setupSavedObjects } from './saved_objects'; const EVENT_LOG_PROVIDER = 'alerting'; export const EVENT_LOG_ACTIONS = { @@ -134,17 +135,7 @@ export class AlertingPlugin { ); } - // Encrypted attributes - plugins.encryptedSavedObjects.registerType({ - type: 'alert', - attributesToEncrypt: new Set(['apiKey']), - attributesToExcludeFromAAD: new Set([ - 'scheduledTaskId', - 'muteAll', - 'mutedInstanceIds', - 'updatedBy', - ]), - }); + setupSavedObjects(core.savedObjects, plugins.encryptedSavedObjects); plugins.eventLog.registerProviderActions(EVENT_LOG_PROVIDER, Object.values(EVENT_LOG_ACTIONS)); this.eventLogger = plugins.eventLog.getLogger({ diff --git a/x-pack/plugins/alerting/server/saved_objects/index.ts b/x-pack/plugins/alerting/server/saved_objects/index.ts new file mode 100644 index 00000000000000..4efec2fe55ef01 --- /dev/null +++ b/x-pack/plugins/alerting/server/saved_objects/index.ts @@ -0,0 +1,33 @@ +/* + * 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 { SavedObjectsServiceSetup } from 'kibana/server'; +import mappings from './mappings.json'; +import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server'; + +export function setupSavedObjects( + savedObjects: SavedObjectsServiceSetup, + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup +) { + savedObjects.registerType({ + name: 'alert', + hidden: false, + namespaceType: 'single', + mappings: mappings.alert, + }); + + // Encrypted attributes + encryptedSavedObjects.registerType({ + type: 'alert', + attributesToEncrypt: new Set(['apiKey']), + attributesToExcludeFromAAD: new Set([ + 'scheduledTaskId', + 'muteAll', + 'mutedInstanceIds', + 'updatedBy', + ]), + }); +} diff --git a/x-pack/legacy/plugins/alerting/server/mappings.json b/x-pack/plugins/alerting/server/saved_objects/mappings.json similarity index 100% rename from x-pack/legacy/plugins/alerting/server/mappings.json rename to x-pack/plugins/alerting/server/saved_objects/mappings.json diff --git a/x-pack/plugins/monitoring/common/constants.ts b/x-pack/plugins/monitoring/common/constants.ts index edd6142455dfb6..eeed7b4d5acf61 100644 --- a/x-pack/plugins/monitoring/common/constants.ts +++ b/x-pack/plugins/monitoring/common/constants.ts @@ -245,7 +245,7 @@ export const ALERT_TYPES = [ALERT_TYPE_LICENSE_EXPIRATION, ALERT_TYPE_CLUSTER_ST /** * Matches the id for the built-in in email action type - * See x-pack/legacy/plugins/actions/server/builtin_action_types/email.ts + * See x-pack/plugins/actions/server/builtin_action_types/email.ts */ export const ALERT_ACTION_TYPE_EMAIL = '.email'; diff --git a/x-pack/plugins/siem/server/lib/detection_engine/scripts/get_action_instances.sh b/x-pack/plugins/siem/server/lib/detection_engine/scripts/get_action_instances.sh index 750c5574f4a729..2028216e6770f2 100755 --- a/x-pack/plugins/siem/server/lib/detection_engine/scripts/get_action_instances.sh +++ b/x-pack/plugins/siem/server/lib/detection_engine/scripts/get_action_instances.sh @@ -10,7 +10,7 @@ set -e ./check_env_variables.sh # Example: ./get_action_instances.sh -# https://github.com/elastic/kibana/blob/master/x-pack/legacy/plugins/actions/README.md#get-apiaction_find-find-actions +# https://github.com/elastic/kibana/blob/master/x-pack/plugins/actions/README.md#get-apiaction_find-find-actions curl -s -k \ -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ -X GET ${KIBANA_URL}${SPACE_URL}/api/action/_getAll \ diff --git a/x-pack/plugins/siem/server/lib/detection_engine/scripts/get_action_types.sh b/x-pack/plugins/siem/server/lib/detection_engine/scripts/get_action_types.sh index 8d8cbdd70a8036..c587e9a2041822 100755 --- a/x-pack/plugins/siem/server/lib/detection_engine/scripts/get_action_types.sh +++ b/x-pack/plugins/siem/server/lib/detection_engine/scripts/get_action_types.sh @@ -10,7 +10,7 @@ set -e ./check_env_variables.sh # Example: ./get_action_types.sh -# https://github.com/elastic/kibana/blob/master/x-pack/legacy/plugins/actions/README.md +# https://github.com/elastic/kibana/blob/master/x-pack/plugins/actions/README.md curl -s -k \ -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ -X GET ${KIBANA_URL}${SPACE_URL}/api/action/types \ diff --git a/x-pack/plugins/task_manager/server/plugin.ts b/x-pack/plugins/task_manager/server/plugin.ts index a70fbdb18c30b6..0f6e3fc31d96d6 100644 --- a/x-pack/plugins/task_manager/server/plugin.ts +++ b/x-pack/plugins/task_manager/server/plugin.ts @@ -12,11 +12,10 @@ import { TaskManager } from './task_manager'; import { createTaskManager } from './create_task_manager'; import { TaskManagerConfig } from './config'; import { Middleware } from './lib/middleware'; +import { setupSavedObjects } from './saved_objects'; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface PluginLegacyDependencies {} export type TaskManagerSetupContract = { - registerLegacyAPI: (legacyDependencies: PluginLegacyDependencies) => Promise; + registerLegacyAPI: () => Promise; } & Pick; export type TaskManagerStartContract = Pick< @@ -35,12 +34,18 @@ export class TaskManagerPlugin this.currentConfig = {} as TaskManagerConfig; } - public setup(core: CoreSetup, plugins: unknown): TaskManagerSetupContract { + public async setup(core: CoreSetup, plugins: unknown): Promise { const logger = this.initContext.logger.get('taskManager'); - const config$ = this.initContext.config.create(); + const config = await this.initContext.config + .create() + .pipe(first()) + .toPromise(); + + setupSavedObjects(core.savedObjects, config); + return { - registerLegacyAPI: once((__LEGACY: PluginLegacyDependencies) => { - config$.subscribe(async config => { + registerLegacyAPI: once(() => { + (async () => { const [{ savedObjects, elasticsearch }] = await core.getStartServices(); const savedObjectsRepository = savedObjects.createInternalRepository(['task']); this.legacyTaskManager$.next( @@ -53,7 +58,7 @@ export class TaskManagerPlugin }) ); this.legacyTaskManager$.complete(); - }); + })(); return this.taskManager; }), addMiddleware: (middleware: Middleware) => { diff --git a/x-pack/plugins/task_manager/server/saved_objects/index.ts b/x-pack/plugins/task_manager/server/saved_objects/index.ts new file mode 100644 index 00000000000000..0ad9021cd7f39c --- /dev/null +++ b/x-pack/plugins/task_manager/server/saved_objects/index.ts @@ -0,0 +1,23 @@ +/* + * 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 { SavedObjectsServiceSetup } from 'kibana/server'; +import mappings from './mappings.json'; +import { TaskManagerConfig } from '../config.js'; + +export function setupSavedObjects( + savedObjects: SavedObjectsServiceSetup, + config: TaskManagerConfig +) { + savedObjects.registerType({ + name: 'task', + namespaceType: 'agnostic', + hidden: true, + convertToAliasScript: `ctx._id = ctx._source.type + ':' + ctx._id`, + mappings: mappings.task, + indexPattern: config.index, + }); +} diff --git a/x-pack/legacy/plugins/task_manager/server/mappings.json b/x-pack/plugins/task_manager/server/saved_objects/mappings.json similarity index 100% rename from x-pack/legacy/plugins/task_manager/server/mappings.json rename to x-pack/plugins/task_manager/server/saved_objects/mappings.json diff --git a/x-pack/legacy/plugins/task_manager/server/migrations.ts b/x-pack/plugins/task_manager/server/saved_objects/migrations.ts similarity index 100% rename from x-pack/legacy/plugins/task_manager/server/migrations.ts rename to x-pack/plugins/task_manager/server/saved_objects/migrations.ts diff --git a/x-pack/plugins/task_manager/server/task_manager.ts b/x-pack/plugins/task_manager/server/task_manager.ts index 24ceea0fe71ef2..2a45a599120ddc 100644 --- a/x-pack/plugins/task_manager/server/task_manager.ts +++ b/x-pack/plugins/task_manager/server/task_manager.ts @@ -240,7 +240,7 @@ export class TaskManager { * @param taskDefinitions - The Kibana task definitions dictionary */ public registerTaskDefinitions(taskDefinitions: TaskDictionary) { - this.assertUninitialized('register task definitions'); + this.assertUninitialized('register task definitions', Object.keys(taskDefinitions).join(', ')); const duplicate = Object.keys(taskDefinitions).find(k => !!this.definitions[k]); if (duplicate) { throw new Error(`Task ${duplicate} is already defined!`); @@ -360,9 +360,11 @@ export class TaskManager { * @param {string} message shown if task manager is already initialized * @returns void */ - private assertUninitialized(message: string) { + private assertUninitialized(message: string, context?: string) { if (this.isStarted) { - throw new Error(`Cannot ${message} after the task manager is initialized!`); + throw new Error( + `${context ? `[${context}] ` : ''}Cannot ${message} after the task manager is initialized` + ); } } } diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts index a7551ad7e2fadd..1244657ed99889 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { getExternalServiceSimulatorPath, ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions'; +} from '../../../../common/fixtures/plugins/actions_simulators'; // node ../scripts/functional_test_runner.js --grep "Actions.servicenddd" --config=test/alerting_api_integration/security_and_spaces/config.ts diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts index 46258e41d5d69d..4151deab45213d 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { getExternalServiceSimulatorPath, ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions'; +} from '../../../../common/fixtures/plugins/actions_simulators'; // eslint-disable-next-line import/no-default-export export default function slackTest({ getService }: FtrProviderContext) { diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts index 338610e9243a40..bae6dada48fb7e 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts @@ -8,7 +8,7 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { getExternalServiceSimulatorPath, ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions'; +} from '../../../../common/fixtures/plugins/actions_simulators'; // eslint-disable-next-line import/no-default-export export default function webhookTest({ getService }: FtrProviderContext) { diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 457b7621e84bd6..870ed3cf0cc0fc 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -8,7 +8,7 @@ import path from 'path'; import { CA_CERT_PATH } from '@kbn/dev-utils'; import { FtrConfigProviderContext } from '@kbn/test/types/ftr'; import { services } from './services'; -import { getAllExternalServiceSimulatorPaths } from './fixtures/plugins/actions'; +import { getAllExternalServiceSimulatorPaths } from './fixtures/plugins/actions_simulators'; interface CreateTestConfigOptions { license: string; @@ -75,7 +75,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) 'some.non.existent.com', ])}`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, - '--xpack.alerting.enabled=true', '--xpack.eventLog.logEntries=true', `--xpack.actions.preconfigured=${JSON.stringify([ { @@ -124,7 +123,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ])}`, ...disabledPlugins.map(key => `--xpack.${key}.enabled=false`), `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'alerts')}`, - `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'actions')}`, + `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'actions_simulators')}`, `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'task_manager')}`, `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'aad')}`, `--server.xsrf.whitelist=${JSON.stringify(getAllExternalServiceSimulatorPaths())}`, diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/index.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/index.ts index 05139213b76b9c..400aec7e11c8de 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/index.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/index.ts @@ -21,7 +21,7 @@ interface CheckAADRequest extends Hapi.Request { // eslint-disable-next-line import/no-default-export export default function(kibana: any) { return new kibana.Plugin({ - require: ['actions', 'alerting', 'encryptedSavedObjects'], + require: ['encryptedSavedObjects'], name: 'aad-fixtures', init(server: Legacy.Server) { const newPlatform = ((server as unknown) as KbnServer).newPlatform; diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/README.md b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/README.md similarity index 100% rename from x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/README.md rename to x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/README.md diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/index.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/index.ts similarity index 98% rename from x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/index.ts rename to x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/index.ts index 019b15cc1862a4..45edd4c092da97 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/index.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/index.ts @@ -36,7 +36,7 @@ export function getAllExternalServiceSimulatorPaths(): string[] { // eslint-disable-next-line import/no-default-export export default function(kibana: any) { return new kibana.Plugin({ - require: ['xpack_main', 'actions'], + require: ['xpack_main'], name: NAME, init: (server: Hapi.Server) => { // this action is specifically NOT enabled in ../../config.ts diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/package.json b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/package.json similarity index 100% rename from x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/package.json rename to x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/package.json diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/pagerduty_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/pagerduty_simulation.ts similarity index 100% rename from x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/pagerduty_simulation.ts rename to x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/pagerduty_simulation.ts diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/servicenow_simulation.ts similarity index 100% rename from x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts rename to x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/servicenow_simulation.ts diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/slack_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/slack_simulation.ts similarity index 100% rename from x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/slack_simulation.ts rename to x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/slack_simulation.ts diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/webhook_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/webhook_simulation.ts similarity index 100% rename from x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/webhook_simulation.ts rename to x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/webhook_simulation.ts diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts index 43d533ad3ae14d..1a47addf36ab33 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts @@ -11,8 +11,8 @@ import { ActionTypeExecutorOptions, ActionType } from '../../../../../../plugins // eslint-disable-next-line import/no-default-export export default function(kibana: any) { return new kibana.Plugin({ - require: ['xpack_main', 'actions', 'alerting', 'elasticsearch'], - name: 'alerts', + require: ['xpack_main', 'elasticsearch'], + name: 'alerts-fixture', init(server: any) { const clusterClient = server.newPlatform.start.core.elasticsearch.legacy.client; server.plugins.xpack_main.registerFeature({ diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager/index.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager/index.ts index 29708f86b0a9b0..ac32f05805e4a3 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager/index.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/task_manager/index.ts @@ -31,7 +31,7 @@ const taskByIdQuery = (id: string) => ({ export default function(kibana: any) { return new kibana.Plugin({ name: 'taskManagerHelpers', - require: ['elasticsearch', 'task_manager'], + require: ['elasticsearch'], config(Joi: any) { return Joi.object({ diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts index eeb0818b5fbabd..4c76ebfb93b0bd 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts @@ -11,7 +11,7 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { getExternalServiceSimulatorPath, ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions'; +} from '../../../../common/fixtures/plugins/actions_simulators'; // eslint-disable-next-line import/no-default-export export default function pagerdutyTest({ getService }: FtrProviderContext) { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index 054f8f6141817e..399ae0f27f5b1a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -11,7 +11,7 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { getExternalServiceSimulatorPath, ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions'; +} from '../../../../common/fixtures/plugins/actions_simulators'; // node ../scripts/functional_test_runner.js --grep "servicenow" --config=test/alerting_api_integration/security_and_spaces/config.ts diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts index e00589b7e85b7b..386254e49c19c8 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts @@ -11,7 +11,7 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { getExternalServiceSimulatorPath, ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions'; +} from '../../../../common/fixtures/plugins/actions_simulators'; // eslint-disable-next-line import/no-default-export export default function slackTest({ getService }: FtrProviderContext) { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts index fd996ea4507bab..9b66326fa6157a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts @@ -10,7 +10,7 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { getExternalServiceSimulatorPath, ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions'; +} from '../../../../common/fixtures/plugins/actions_simulators'; const defaultValues: Record = { headers: null, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts index 5122a74d53b725..112149a32649a2 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts @@ -10,7 +10,7 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; import { getExternalServiceSimulatorPath, ExternalServiceSimulator, -} from '../../../../common/fixtures/plugins/actions'; +} from '../../../../common/fixtures/plugins/actions_simulators'; // eslint-disable-next-line import/no-default-export export default function webhookTest({ getService }: FtrProviderContext) { diff --git a/x-pack/test/detection_engine_api_integration/common/config.ts b/x-pack/test/detection_engine_api_integration/common/config.ts index e89352118990a1..1e6600c7cd2c0d 100644 --- a/x-pack/test/detection_engine_api_integration/common/config.ts +++ b/x-pack/test/detection_engine_api_integration/common/config.ts @@ -78,7 +78,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) 'some.non.existent.com', ])}`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, - '--xpack.alerting.enabled=true', '--xpack.eventLog.logEntries=true', ...disabledPlugins.map(key => `--xpack.${key}.enabled=false`), `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'alerts')}`, diff --git a/x-pack/test/functional_with_es_ssl/config.ts b/x-pack/test/functional_with_es_ssl/config.ts index a620b1d9533767..71b22a336f6b92 100644 --- a/x-pack/test/functional_with_es_ssl/config.ts +++ b/x-pack/test/functional_with_es_ssl/config.ts @@ -50,8 +50,6 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) { `--elasticsearch.hosts=https://${servers.elasticsearch.hostname}:${servers.elasticsearch.port}`, `--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`, `--plugin-path=${join(__dirname, 'fixtures', 'plugins', 'alerts')}`, - '--xpack.actions.enabled=true', - '--xpack.alerting.enabled=true', `--xpack.actions.preconfigured=${JSON.stringify([ { id: 'my-slack1', diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/kibana.json b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/kibana.json new file mode 100644 index 00000000000000..416ef7fa345919 --- /dev/null +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/kibana.json @@ -0,0 +1,9 @@ +{ + "id": "sample_task_plugin", + "version": "1.0.0", + "kibanaVersion": "kibana", + "configPath": ["xpack"], + "requiredPlugins": ["taskManager"], + "server": true, + "ui": false +} diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/package.json b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/package.json new file mode 100644 index 00000000000000..c8d47decd94c1c --- /dev/null +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/package.json @@ -0,0 +1,18 @@ +{ + "name": "sample_task_plugin", + "version": "1.0.0", + "kibana": { + "version": "kibana", + "templateVersion": "1.0.0" + }, + "main": "target/test/plugin_api_integration/plugins/sample_task_plugin", + "scripts": { + "kbn": "node ../../../../../scripts/kbn.js", + "build": "rm -rf './target' && tsc" + }, + "devDependencies": { + "typescript": "3.7.2" + }, + "license": "Apache-2.0", + "dependencies": {} +} diff --git a/x-pack/legacy/plugins/actions/index.ts b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/index.ts similarity index 65% rename from x-pack/legacy/plugins/actions/index.ts rename to x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/index.ts index 276d1ea3accea6..77233f463734a1 100644 --- a/x-pack/legacy/plugins/actions/index.ts +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/index.ts @@ -4,4 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './server/'; +import { SampleTaskManagerFixturePlugin } from './plugin'; + +export const plugin = () => new SampleTaskManagerFixturePlugin(); diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts new file mode 100644 index 00000000000000..1fee2decbcba94 --- /dev/null +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/init_routes.ts @@ -0,0 +1,252 @@ +/* + * 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, + CoreSetup, +} from 'kibana/server'; +import { EventEmitter } from 'events'; +import { TaskManagerStartContract } from '../../../../../plugins/task_manager/server'; + +const scope = 'testing'; +const taskManagerQuery = { + bool: { + filter: { + bool: { + must: [ + { + term: { + 'task.scope': scope, + }, + }, + ], + }, + }, + }, +}; + +export function initRoutes( + router: IRouter, + core: CoreSetup, + taskManagerStart: Promise, + taskTestingEvents: EventEmitter +) { + async function ensureIndexIsRefreshed() { + return await core.elasticsearch.adminClient.callAsInternalUser('indices.refresh', { + index: '.kibana_task_manager', + }); + } + + router.post( + { + path: `/api/sample_tasks/schedule`, + validate: { + body: schema.object({ + task: schema.object({ + taskType: schema.string(), + schedule: schema.maybe( + schema.object({ + interval: schema.string(), + }) + ), + interval: schema.maybe(schema.string()), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + state: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + id: schema.maybe(schema.string()), + }), + }), + }, + }, + async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + try { + const taskManager = await taskManagerStart; + const { task: taskFields } = req.body; + const task = { + ...taskFields, + scope: [scope], + }; + + const taskResult = await taskManager.schedule(task, { req }); + + return res.ok({ body: taskResult }); + } catch (err) { + return res.internalError({ body: err }); + } + } + ); + + router.post( + { + path: `/api/sample_tasks/run_now`, + validate: { + body: schema.object({ + task: schema.object({ + id: schema.string({}), + }), + }), + }, + }, + async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + const { + task: { id }, + } = req.body; + try { + const taskManager = await taskManagerStart; + return res.ok({ body: await taskManager.runNow(id) }); + } catch (err) { + return res.ok({ body: { id, error: `${err}` } }); + } + } + ); + + router.post( + { + path: `/api/sample_tasks/ensure_scheduled`, + validate: { + body: schema.object({ + task: schema.object({ + taskType: schema.string(), + params: schema.object({}), + state: schema.maybe(schema.object({})), + id: schema.maybe(schema.string()), + }), + }), + }, + }, + async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + try { + const { task: taskFields } = req.body; + const task = { + ...taskFields, + scope: [scope], + }; + + const taskManager = await taskManagerStart; + const taskResult = await taskManager.ensureScheduled(task, { req }); + + return res.ok({ body: taskResult }); + } catch (err) { + return res.ok({ body: err }); + } + } + ); + + router.post( + { + path: `/api/sample_tasks/event`, + validate: { + body: schema.object({ + event: schema.string(), + data: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + }), + }, + }, + async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + try { + const { event, data } = req.body; + taskTestingEvents.emit(event, data); + return res.ok({ body: event }); + } catch (err) { + return res.ok({ body: err }); + } + } + ); + + router.get( + { + path: `/api/sample_tasks`, + validate: {}, + }, + async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + try { + const taskManager = await taskManagerStart; + return res.ok({ + body: await taskManager.fetch({ + query: taskManagerQuery, + }), + }); + } catch (err) { + return res.ok({ body: err }); + } + } + ); + + router.get( + { + path: `/api/sample_tasks/task/{taskId}`, + validate: { + params: schema.object({ + taskId: schema.string(), + }), + }, + }, + async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + try { + await ensureIndexIsRefreshed(); + const taskManager = await taskManagerStart; + return res.ok({ body: await taskManager.get(req.params.taskId) }); + } catch (err) { + return res.ok({ body: err }); + } + return res.ok({ body: {} }); + } + ); + + router.delete( + { + path: `/api/sample_tasks`, + validate: {}, + }, + async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + try { + let tasksFound = 0; + const taskManager = await taskManagerStart; + do { + const { docs: tasks } = await taskManager.fetch({ + query: taskManagerQuery, + }); + tasksFound = tasks.length; + await Promise.all(tasks.map(task => taskManager.remove(task.id))); + } while (tasksFound > 0); + return res.ok({ body: 'OK' }); + } catch (err) { + return res.ok({ body: err }); + } + } + ); +} diff --git a/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/plugin.ts b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/plugin.ts new file mode 100644 index 00000000000000..508d58b8f0ca96 --- /dev/null +++ b/x-pack/test/plugin_api_integration/plugins/sample_task_plugin/server/plugin.ts @@ -0,0 +1,164 @@ +/* + * 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 { Plugin, CoreSetup, CoreStart } from 'kibana/server'; +import { EventEmitter } from 'events'; +import { Subject } from 'rxjs'; +import { first } from 'rxjs/operators'; +import { initRoutes } from './init_routes'; +import { + TaskManagerSetupContract, + TaskManagerStartContract, + ConcreteTaskInstance, +} from '../../../../../plugins/task_manager/server'; +import { DEFAULT_MAX_WORKERS } from '../../../../../plugins/task_manager/server/config'; + +// this plugin's dependendencies +export interface SampleTaskManagerFixtureSetupDeps { + taskManager: TaskManagerSetupContract; +} +export interface SampleTaskManagerFixtureStartDeps { + taskManager: TaskManagerStartContract; +} + +export class SampleTaskManagerFixturePlugin + implements + Plugin { + taskManagerStart$: Subject = new Subject(); + taskManagerStart: Promise = this.taskManagerStart$ + .pipe(first()) + .toPromise(); + + public setup(core: CoreSetup, { taskManager }: SampleTaskManagerFixtureSetupDeps) { + const taskTestingEvents = new EventEmitter(); + taskTestingEvents.setMaxListeners(DEFAULT_MAX_WORKERS * 2); + + const defaultSampleTaskConfig = { + timeout: '1m', + // This task allows tests to specify its behavior (whether it reschedules itself, whether it errors, etc) + // taskInstance.params has the following optional fields: + // nextRunMilliseconds: number - If specified, the run method will return a runAt that is now + nextRunMilliseconds + // failWith: string - If specified, the task will throw an error with the specified message + // failOn: number - If specified, the task will only throw the `failWith` error when `count` equals to the failOn value + // waitForParams : boolean - should the task stall ands wait to receive params asynchronously before using the default params + // waitForEvent : string - if provided, the task will stall (after completing the run) and wait for an asyn event before completing + createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => ({ + async run() { + const { params, state, id } = taskInstance; + const prevState = state || { count: 0 }; + + const count = (prevState.count || 0) + 1; + + const runParams = { + ...params, + // if this task requires custom params provided async - wait for them + ...(params.waitForParams ? await once(taskTestingEvents, id) : {}), + }; + + if (runParams.failWith) { + if (!runParams.failOn || (runParams.failOn && count === runParams.failOn)) { + throw new Error(runParams.failWith); + } + } + + await core.elasticsearch.adminClient.callAsInternalUser('index', { + index: '.kibana_task_manager_test_result', + body: { + type: 'task', + taskId: taskInstance.id, + params: JSON.stringify(runParams), + state: JSON.stringify(state), + ranAt: new Date(), + }, + refresh: true, + }); + + // Stall task run until a certain event is triggered + if (runParams.waitForEvent) { + await once(taskTestingEvents, runParams.waitForEvent); + } + + return { + state: { count }, + runAt: millisecondsFromNow(runParams.nextRunMilliseconds), + }; + }, + }), + }; + + taskManager.registerTaskDefinitions({ + sampleTask: { + ...defaultSampleTaskConfig, + type: 'sampleTask', + title: 'Sample Task', + description: 'A sample task for testing the task_manager.', + }, + singleAttemptSampleTask: { + ...defaultSampleTaskConfig, + type: 'singleAttemptSampleTask', + title: 'Failing Sample Task', + description: + 'A sample task for testing the task_manager that fails on the first attempt to run.', + // fail after the first failed run + maxAttempts: 1, + }, + }); + + taskManager.addMiddleware({ + async beforeSave({ taskInstance, ...opts }) { + const modifiedInstance = { + ...taskInstance, + params: { + originalParams: taskInstance.params, + superFly: 'My middleware param!', + }, + }; + + return { + ...opts, + taskInstance: modifiedInstance, + }; + }, + + async beforeRun({ taskInstance, ...opts }) { + return { + ...opts, + taskInstance: { + ...taskInstance, + params: taskInstance.params.originalParams, + }, + }; + }, + + async beforeMarkRunning(context) { + return context; + }, + }); + initRoutes(core.http.createRouter(), core, this.taskManagerStart, taskTestingEvents); + } + + public start(core: CoreStart, { taskManager }: SampleTaskManagerFixtureStartDeps) { + this.taskManagerStart$.next(taskManager); + this.taskManagerStart$.complete(); + } + public stop() {} +} + +function millisecondsFromNow(ms: number) { + if (!ms) { + return; + } + + const dt = new Date(); + dt.setTime(dt.getTime() + ms); + return dt; +} + +const once = function(emitter: EventEmitter, event: string): Promise> { + return new Promise(resolve => { + emitter.once(event, data => resolve(data || {})); + }); +}; diff --git a/x-pack/test/plugin_api_integration/plugins/task_manager/index.js b/x-pack/test/plugin_api_integration/plugins/task_manager/index.js deleted file mode 100644 index e5b645367b8b71..00000000000000 --- a/x-pack/test/plugin_api_integration/plugins/task_manager/index.js +++ /dev/null @@ -1,150 +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. - */ - -const { DEFAULT_MAX_WORKERS } = require('../../../../plugins/task_manager/server/config.ts'); -const { EventEmitter } = require('events'); - -import { initRoutes } from './init_routes'; - -const once = function(emitter, event) { - return new Promise(resolve => { - emitter.once(event, data => resolve(data || {})); - }); -}; - -export default function TaskTestingAPI(kibana) { - const taskTestingEvents = new EventEmitter(); - taskTestingEvents.setMaxListeners(DEFAULT_MAX_WORKERS * 2); - - return new kibana.Plugin({ - name: 'sampleTask', - require: ['elasticsearch', 'task_manager'], - - config(Joi) { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - - init(server) { - const taskManager = { - ...server.newPlatform.setup.plugins.taskManager, - ...server.newPlatform.start.plugins.taskManager, - }; - const legacyTaskManager = server.plugins.task_manager; - - const defaultSampleTaskConfig = { - timeout: '1m', - // This task allows tests to specify its behavior (whether it reschedules itself, whether it errors, etc) - // taskInstance.params has the following optional fields: - // nextRunMilliseconds: number - If specified, the run method will return a runAt that is now + nextRunMilliseconds - // failWith: string - If specified, the task will throw an error with the specified message - // failOn: number - If specified, the task will only throw the `failWith` error when `count` equals to the failOn value - // waitForParams : boolean - should the task stall ands wait to receive params asynchronously before using the default params - // waitForEvent : string - if provided, the task will stall (after completing the run) and wait for an asyn event before completing - createTaskRunner: ({ taskInstance }) => ({ - async run() { - const { params, state, id } = taskInstance; - const prevState = state || { count: 0 }; - - const count = (prevState.count || 0) + 1; - - const runParams = { - ...params, - // if this task requires custom params provided async - wait for them - ...(params.waitForParams ? await once(taskTestingEvents, id) : {}), - }; - - if (runParams.failWith) { - if (!runParams.failOn || (runParams.failOn && count === runParams.failOn)) { - throw new Error(runParams.failWith); - } - } - - const callCluster = server.plugins.elasticsearch.getCluster('admin') - .callWithInternalUser; - await callCluster('index', { - index: '.kibana_task_manager_test_result', - body: { - type: 'task', - taskId: taskInstance.id, - params: JSON.stringify(runParams), - state: JSON.stringify(state), - ranAt: new Date(), - }, - refresh: true, - }); - - // Stall task run until a certain event is triggered - if (runParams.waitForEvent) { - await once(taskTestingEvents, runParams.waitForEvent); - } - - return { - state: { count }, - runAt: millisecondsFromNow(runParams.nextRunMilliseconds), - }; - }, - }), - }; - - taskManager.registerTaskDefinitions({ - sampleTask: { - ...defaultSampleTaskConfig, - title: 'Sample Task', - description: 'A sample task for testing the task_manager.', - }, - singleAttemptSampleTask: { - ...defaultSampleTaskConfig, - title: 'Failing Sample Task', - description: - 'A sample task for testing the task_manager that fails on the first attempt to run.', - // fail after the first failed run - maxAttempts: 1, - }, - }); - - taskManager.addMiddleware({ - async beforeSave({ taskInstance, ...opts }) { - const modifiedInstance = { - ...taskInstance, - params: { - originalParams: taskInstance.params, - superFly: 'My middleware param!', - }, - }; - - return { - ...opts, - taskInstance: modifiedInstance, - }; - }, - - async beforeRun({ taskInstance, ...opts }) { - return { - ...opts, - taskInstance: { - ...taskInstance, - params: taskInstance.params.originalParams, - }, - }; - }, - }); - - initRoutes(server, taskManager, legacyTaskManager, taskTestingEvents); - }, - }); -} - -function millisecondsFromNow(ms) { - if (!ms) { - return; - } - - const dt = new Date(); - dt.setTime(dt.getTime() + ms); - return dt; -} diff --git a/x-pack/test/plugin_api_integration/plugins/task_manager/init_routes.js b/x-pack/test/plugin_api_integration/plugins/task_manager/init_routes.js deleted file mode 100644 index 785fbed3414237..00000000000000 --- a/x-pack/test/plugin_api_integration/plugins/task_manager/init_routes.js +++ /dev/null @@ -1,236 +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'; - -const scope = 'testing'; -const taskManagerQuery = { - bool: { - filter: { - bool: { - must: [ - { - term: { - 'task.scope': scope, - }, - }, - ], - }, - }, - }, -}; - -export function initRoutes(server, taskManager, legacyTaskManager, taskTestingEvents) { - const callCluster = server.plugins.elasticsearch.getCluster('admin').callWithInternalUser; - - async function ensureIndexIsRefreshed() { - return await callCluster('indices.refresh', { - index: '.kibana_task_manager', - }); - } - - server.route({ - path: '/api/sample_tasks/schedule', - method: 'POST', - config: { - validate: { - payload: Joi.object({ - task: Joi.object({ - taskType: Joi.string().required(), - schedule: Joi.object({ - interval: Joi.string(), - }).optional(), - interval: Joi.string().optional(), - params: Joi.object().required(), - state: Joi.object().optional(), - id: Joi.string().optional(), - }), - }), - }, - }, - async handler(request) { - try { - const { task: taskFields } = request.payload; - const task = { - ...taskFields, - scope: [scope], - }; - - const taskResult = await taskManager.schedule(task, { request }); - - return taskResult; - } catch (err) { - return err; - } - }, - }); - - /* - Schedule using legacy Api - */ - server.route({ - path: '/api/sample_tasks/schedule_legacy', - method: 'POST', - config: { - validate: { - payload: Joi.object({ - task: Joi.object({ - taskType: Joi.string().required(), - schedule: Joi.object({ - interval: Joi.string(), - }).optional(), - interval: Joi.string().optional(), - params: Joi.object().required(), - state: Joi.object().optional(), - id: Joi.string().optional(), - }), - }), - }, - }, - async handler(request) { - try { - const { task: taskFields } = request.payload; - const task = { - ...taskFields, - scope: [scope], - }; - - const taskResult = await legacyTaskManager.schedule(task, { request }); - - return taskResult; - } catch (err) { - return err; - } - }, - }); - - server.route({ - path: '/api/sample_tasks/run_now', - method: 'POST', - config: { - validate: { - payload: Joi.object({ - task: Joi.object({ - id: Joi.string().optional(), - }), - }), - }, - }, - async handler(request) { - const { - task: { id }, - } = request.payload; - try { - return await taskManager.runNow(id); - } catch (err) { - return { id, error: `${err}` }; - } - }, - }); - - server.route({ - path: '/api/sample_tasks/ensure_scheduled', - method: 'POST', - config: { - validate: { - payload: Joi.object({ - task: Joi.object({ - taskType: Joi.string().required(), - params: Joi.object().required(), - state: Joi.object().optional(), - id: Joi.string().optional(), - }), - }), - }, - }, - async handler(request) { - try { - const { task: taskFields } = request.payload; - const task = { - ...taskFields, - scope: [scope], - }; - - const taskResult = await taskManager.ensureScheduled(task, { request }); - - return taskResult; - } catch (err) { - return err; - } - }, - }); - - server.route({ - path: '/api/sample_tasks/event', - method: 'POST', - config: { - validate: { - payload: Joi.object({ - event: Joi.string().required(), - data: Joi.object() - .optional() - .default({}), - }), - }, - }, - async handler(request) { - try { - const { event, data } = request.payload; - taskTestingEvents.emit(event, data); - return { event }; - } catch (err) { - return err; - } - }, - }); - - server.route({ - path: '/api/sample_tasks', - method: 'GET', - async handler() { - try { - return taskManager.fetch({ - query: taskManagerQuery, - }); - } catch (err) { - return err; - } - }, - }); - - server.route({ - path: '/api/sample_tasks/task/{taskId}', - method: 'GET', - async handler(request) { - try { - await ensureIndexIsRefreshed(); - return await taskManager.get(request.params.taskId); - } catch (err) { - return err; - } - }, - }); - - server.route({ - path: '/api/sample_tasks', - method: 'DELETE', - async handler() { - try { - let tasksFound = 0; - do { - const { docs: tasks } = await taskManager.fetch({ - query: taskManagerQuery, - }); - tasksFound = tasks.length; - await Promise.all(tasks.map(task => taskManager.remove(task.id))); - } while (tasksFound > 0); - return 'OK'; - } catch (err) { - return err; - } - }, - }); -} diff --git a/x-pack/test/plugin_api_integration/plugins/task_manager/package.json b/x-pack/test/plugin_api_integration/plugins/task_manager/package.json deleted file mode 100644 index ec63c512e9cd79..00000000000000 --- a/x-pack/test/plugin_api_integration/plugins/task_manager/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "sample_task_plugin", - "version": "1.0.0", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "dependencies": { - "joi": "^13.5.2" - } -} diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js index e8f976d5ae6e30..00cefa42711c9c 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js @@ -11,7 +11,7 @@ import supertestAsPromised from 'supertest-as-promised'; const { task: { properties: taskManagerIndexMapping }, -} = require('../../../../legacy/plugins/task_manager/server/mappings.json'); +} = require('../../../../plugins/task_manager/server/saved_objects/mappings.json'); const { DEFAULT_MAX_WORKERS, @@ -90,15 +90,6 @@ export default function({ getService }) { .then(response => response.body); } - function scheduleTaskUsingLegacyApi(task) { - return supertest - .post('/api/sample_tasks/schedule_legacy') - .set('kbn-xsrf', 'xxx') - .send({ task }) - .expect(200) - .then(response => response.body); - } - function runTaskNow(task) { return supertest .post('/api/sample_tasks/run_now') @@ -587,15 +578,5 @@ export default function({ getService }) { expect(getTaskById(tasks, longRunningTask.id).state.count).to.eql(1); }); }); - - it('should retain the legacy api until v8.0.0', async () => { - const result = await scheduleTaskUsingLegacyApi({ - id: 'task-with-legacy-api', - taskType: 'sampleTask', - params: {}, - }); - - expect(result.id).to.be('task-with-legacy-api'); - }); }); } From af2e86f949b989d7dcbcd05d5af46ffa831e1e84 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Wed, 29 Apr 2020 10:50:03 -0400 Subject: [PATCH 13/26] [Lens] Fix flaky test by closing options after use (#64714) Co-authored-by: Elastic Machine --- .../test/functional/page_objects/lens_page.ts | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 1bf637c50b0ba4..57b2847cc2e500 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -12,6 +12,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont const testSubjects = getService('testSubjects'); const retry = getService('retry'); const find = getService('find'); + const comboBox = getService('comboBox'); const PageObjects = getPageObjects([ 'header', 'common', @@ -107,20 +108,17 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont * @param opts.operation - the desired operation ID for the dimension * @param opts.field - the desired field for the dimension */ - async configureDimension(opts: { dimension: string; operation?: string; field?: string }) { + async configureDimension(opts: { dimension: string; operation: string; field: string }) { await find.clickByCssSelector(opts.dimension); - if (opts.operation) { - await find.clickByCssSelector( - `[data-test-subj="lns-indexPatternDimensionIncompatible-${opts.operation}"], - [data-test-subj="lns-indexPatternDimension-${opts.operation}"]` - ); - } + await find.clickByCssSelector( + `[data-test-subj="lns-indexPatternDimensionIncompatible-${opts.operation}"], + [data-test-subj="lns-indexPatternDimension-${opts.operation}"]` + ); - if (opts.field) { - await testSubjects.click('indexPattern-dimension-field'); - await testSubjects.click(`lns-fieldOption-${opts.field}`); - } + const target = await testSubjects.find('indexPattern-dimension-field'); + await comboBox.openOptionsList(target); + await comboBox.setElement(target, opts.field); }, /** From f8dc041b855569bcfe422992e898812c10ef94d0 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Wed, 29 Apr 2020 11:31:35 -0400 Subject: [PATCH 14/26] [Ingest] Use agent template embeded in the pkg registry response (#64705) --- .../ingest_manager/common/types/models/epm.ts | 1 + .../server/routes/datasource/handlers.ts | 28 ++++---- .../server/services/datasource.test.ts | 64 +++++++++++-------- .../server/services/datasource.ts | 37 +++++++---- .../ingest_manager/server/services/setup.ts | 2 +- 5 files changed, 79 insertions(+), 53 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/types/models/epm.ts b/x-pack/plugins/ingest_manager/common/types/models/epm.ts index fb6bf235d1e26b..05e160cdfb81ac 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/epm.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/epm.ts @@ -97,6 +97,7 @@ export interface RegistryStream { description?: string; enabled?: boolean; vars?: RegistryVarsEntry[]; + template?: string; } export type RequirementVersion = string; diff --git a/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts index 56d6053a1451b7..8f07e3ed1de022 100644 --- a/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts @@ -7,7 +7,7 @@ import { TypeOf } from '@kbn/config-schema'; import Boom from 'boom'; import { RequestHandler } from 'src/core/server'; import { appContextService, datasourceService } from '../../services'; -import { ensureInstalledPackage } from '../../services/epm/packages'; +import { ensureInstalledPackage, getPackageInfo } from '../../services/epm/packages'; import { GetDatasourcesRequestSchema, GetOneDatasourceRequestSchema, @@ -85,12 +85,13 @@ export const createDatasourceHandler: RequestHandler< pkgName: request.body.package.name, callCluster, }); - + const pkgInfo = await getPackageInfo({ + savedObjectsClient: soClient, + pkgName: request.body.package.name, + pkgVersion: request.body.package.version, + }); newData.inputs = (await datasourceService.assignPackageStream( - { - pkgName: request.body.package.name, - pkgVersion: request.body.package.version, - }, + pkgInfo, request.body.inputs )) as TypeOf['inputs']; } @@ -127,13 +128,14 @@ export const updateDatasourceHandler: RequestHandler< const pkg = newData.package || datasource.package; const inputs = newData.inputs || datasource.inputs; if (pkg && (newData.inputs || newData.package)) { - newData.inputs = (await datasourceService.assignPackageStream( - { - pkgName: pkg.name, - pkgVersion: pkg.version, - }, - inputs - )) as TypeOf['inputs']; + const pkgInfo = await getPackageInfo({ + savedObjectsClient: soClient, + pkgName: pkg.name, + pkgVersion: pkg.version, + }); + newData.inputs = (await datasourceService.assignPackageStream(pkgInfo, inputs)) as TypeOf< + typeof CreateDatasourceRequestSchema.body + >['inputs']; } const updatedDatasource = await datasourceService.update( diff --git a/x-pack/plugins/ingest_manager/server/services/datasource.test.ts b/x-pack/plugins/ingest_manager/server/services/datasource.test.ts index 4cbbadce7f5bb9..3682ae6d1167b9 100644 --- a/x-pack/plugins/ingest_manager/server/services/datasource.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/datasource.test.ts @@ -5,39 +5,38 @@ */ import { datasourceService } from './datasource'; +import { PackageInfo } from '../types'; -async function mockedGetAssetsData(_a: any, _b: any, dataset: string) { - if (dataset === 'dataset1') { - return [ - { - buffer: Buffer.from(` +const TEMPLATE = ` type: log metricset: ["dataset1"] paths: {{#each paths}} - {{this}} {{/each}} -`), - }, - ]; - } - return []; -} - -jest.mock('./epm/packages/assets', () => { - return { - getAssetsDataForPackageKey: mockedGetAssetsData, - }; -}); +`; describe('Datasource service', () => { describe('assignPackageStream', () => { - it('should work with cofig variables from the stream', async () => { + it('should work with config variables from the stream', async () => { const inputs = await datasourceService.assignPackageStream( - { - pkgName: 'package', - pkgVersion: '1.0.0', - }, + ({ + datasources: [ + { + inputs: [ + { + type: 'log', + streams: [ + { + dataset: 'package.dataset1', + template: TEMPLATE, + }, + ], + }, + ], + }, + ], + } as unknown) as PackageInfo, [ { type: 'log', @@ -85,10 +84,23 @@ describe('Datasource service', () => { it('should work with config variables at the input level', async () => { const inputs = await datasourceService.assignPackageStream( - { - pkgName: 'package', - pkgVersion: '1.0.0', - }, + ({ + datasources: [ + { + inputs: [ + { + type: 'log', + streams: [ + { + dataset: 'package.dataset1', + template: TEMPLATE, + }, + ], + }, + ], + }, + ], + } as unknown) as PackageInfo, [ { type: 'log', diff --git a/x-pack/plugins/ingest_manager/server/services/datasource.ts b/x-pack/plugins/ingest_manager/server/services/datasource.ts index 55edfe67e540ad..0a5ba43e40fba9 100644 --- a/x-pack/plugins/ingest_manager/server/services/datasource.ts +++ b/x-pack/plugins/ingest_manager/server/services/datasource.ts @@ -10,13 +10,13 @@ import { packageToConfigDatasource, DatasourceInput, DatasourceInputStream, + PackageInfo, } from '../../common'; import { DATASOURCE_SAVED_OBJECT_TYPE } from '../constants'; import { NewDatasource, Datasource, ListWithKuery } from '../types'; import { agentConfigService } from './agent_config'; import { getPackageInfo, getInstallation } from './epm/packages'; import { outputService } from './output'; -import { getAssetsDataForPackageKey } from './epm/packages/assets'; import { createStream } from './epm/agent/agent'; const SAVED_OBJECT_TYPE = DATASOURCE_SAVED_OBJECT_TYPE; @@ -200,20 +200,16 @@ class DatasourceService { } public async assignPackageStream( - pkgInfo: { pkgName: string; pkgVersion: string }, + pkgInfo: PackageInfo, inputs: DatasourceInput[] ): Promise { const inputsPromises = inputs.map(input => _assignPackageStreamToInput(pkgInfo, input)); + return Promise.all(inputsPromises); } } -const _isAgentStream = (p: string) => !!p.match(/agent\/stream\/stream\.yml/); - -async function _assignPackageStreamToInput( - pkgInfo: { pkgName: string; pkgVersion: string }, - input: DatasourceInput -) { +async function _assignPackageStreamToInput(pkgInfo: PackageInfo, input: DatasourceInput) { const streamsPromises = input.streams.map(stream => _assignPackageStreamToStream(pkgInfo, input, stream) ); @@ -223,7 +219,7 @@ async function _assignPackageStreamToInput( } async function _assignPackageStreamToStream( - pkgInfo: { pkgName: string; pkgVersion: string }, + pkgInfo: PackageInfo, input: DatasourceInput, stream: DatasourceInputStream ) { @@ -231,18 +227,33 @@ async function _assignPackageStreamToStream( return { ...stream, agent_stream: undefined }; } const dataset = getDataset(stream.dataset); - const assetsData = await getAssetsDataForPackageKey(pkgInfo, _isAgentStream, dataset); + const datasource = pkgInfo.datasources?.[0]; + if (!datasource) { + throw new Error('Stream template not found, no datasource'); + } + + const inputFromPkg = datasource.inputs.find(pkgInput => pkgInput.type === input.type); + if (!inputFromPkg) { + throw new Error(`Stream template not found, unable to found input ${input.type}`); + } - const [pkgStream] = assetsData; - if (!pkgStream || !pkgStream.buffer) { + const streamFromPkg = inputFromPkg.streams.find( + pkgStream => pkgStream.dataset === stream.dataset + ); + if (!streamFromPkg) { + throw new Error(`Stream template not found, unable to found stream ${stream.dataset}`); + } + + if (!streamFromPkg.template) { throw new Error(`Stream template not found for dataset ${dataset}`); } const yaml = createStream( // Populate template variables from input vars and stream vars Object.assign({}, input.vars, stream.vars), - pkgStream.buffer.toString() + streamFromPkg.template ); + stream.agent_stream = yaml; return { ...stream }; diff --git a/x-pack/plugins/ingest_manager/server/services/setup.ts b/x-pack/plugins/ingest_manager/server/services/setup.ts index 206ad76703cf56..390e240841611e 100644 --- a/x-pack/plugins/ingest_manager/server/services/setup.ts +++ b/x-pack/plugins/ingest_manager/server/services/setup.ts @@ -145,7 +145,7 @@ async function addPackageToConfig( config.namespace ); newDatasource.inputs = await datasourceService.assignPackageStream( - { pkgName: packageToInstall.name, pkgVersion: packageToInstall.version }, + packageInfo, newDatasource.inputs ); From 7354ff667649336b5960bc7a0dd72273b9aaa02f Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 29 Apr 2020 16:38:41 +0100 Subject: [PATCH 15/26] Revert "chore(NA): add async import into infra plugin to reduce apm bundle size (#63292)" (#64764) This reverts commit 30439f6df0778582e53a6d51ec5f2b2f9885697f. --- x-pack/plugins/infra/public/plugin.ts | 29 +++++---------------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/infra/public/plugin.ts b/x-pack/plugins/infra/public/plugin.ts index 26f206c06203b8..40366b2a54f243 100644 --- a/x-pack/plugins/infra/public/plugin.ts +++ b/x-pack/plugins/infra/public/plugin.ts @@ -21,6 +21,8 @@ import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/p import { DataEnhancedSetup, DataEnhancedStart } from '../../data_enhanced/public'; import { TriggersAndActionsUIPublicPluginSetup } from '../../../plugins/triggers_actions_ui/public'; +import { getAlertType as getMetricsAlertType } from './components/alerting/metrics/metric_threshold_alert_type'; +import { getAlertType as getLogsAlertType } from './components/alerting/logs/log_threshold_alert_type'; export type ClientSetup = void; export type ClientStart = void; @@ -51,6 +53,9 @@ export class Plugin setup(core: CoreSetup, pluginsSetup: ClientPluginsSetup) { registerFeatures(pluginsSetup.home); + pluginsSetup.triggers_actions_ui.alertTypeRegistry.register(getMetricsAlertType()); + pluginsSetup.triggers_actions_ui.alertTypeRegistry.register(getLogsAlertType()); + core.application.register({ id: 'logs', title: i18n.translate('xpack.infra.logs.pluginTitle', { @@ -65,8 +70,6 @@ export class Plugin const plugins = getMergedPlugins(pluginsSetup, pluginsStart as ClientPluginsStart); const { startApp, composeLibs, LogsRouter } = await this.downloadAssets(); - await this.registerLogsAlertType(pluginsSetup); - return startApp( composeLibs(coreStart), coreStart, @@ -92,8 +95,6 @@ export class Plugin const plugins = getMergedPlugins(pluginsSetup, pluginsStart as ClientPluginsStart); const { startApp, composeLibs, MetricsRouter } = await this.downloadAssets(); - await this.registerMetricsAlertType(pluginsSetup); - return startApp( composeLibs(coreStart), coreStart, @@ -137,24 +138,4 @@ export class Plugin MetricsRouter, }; } - - // NOTE: apm is importing from `infra/public` and async importing that - // allow us to reduce the apm bundle size - private async registerLogsAlertType(pluginsSetup: ClientPluginsSetup) { - const { getAlertType } = await import('./components/alerting/logs/log_threshold_alert_type'); - - if (!pluginsSetup.triggers_actions_ui.alertTypeRegistry.has(getAlertType().id)) { - pluginsSetup.triggers_actions_ui.alertTypeRegistry.register(getAlertType()); - } - } - - private async registerMetricsAlertType(pluginsSetup: ClientPluginsSetup) { - const { getAlertType } = await import( - './components/alerting/metrics/metric_threshold_alert_type' - ); - - if (!pluginsSetup.triggers_actions_ui.alertTypeRegistry.has(getAlertType().id)) { - pluginsSetup.triggers_actions_ui.alertTypeRegistry.register(getAlertType()); - } - } } From 5ee6dcd14d3734f3a9be3867f2cf0ac0e58df33f Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Wed, 29 Apr 2020 18:15:57 +0200 Subject: [PATCH 16/26] Lazy load Security plugin management apps. (#64511) --- .../account_management_app.ts | 8 +++-- .../access_agreement/_index.scss | 1 - ...t_page.scss => access_agreement_page.scss} | 0 .../access_agreement_page.tsx | 2 +- ...ge.scss => authentication_state_page.scss} | 0 .../authentication_state_page.tsx | 2 +- .../{_login_page.scss => login_page.scss} | 0 .../authentication/login/login_page.tsx | 2 +- x-pack/plugins/security/public/index.scss | 4 --- x-pack/plugins/security/public/index.ts | 1 - .../security/public/management/_index.scss | 3 -- .../api_keys/api_keys_management_app.tsx | 13 ++++++-- .../management/role_mappings/_index.scss | 1 - .../edit_role_mapping/_index.scss | 1 - .../rule_editor_panel/_index.scss | 1 - ...itor_group.scss => rule_group_editor.scss} | 0 .../rule_editor_panel/rule_group_editor.tsx | 2 ++ .../role_mappings_management_app.tsx | 19 ++++++++--- .../public/management/roles/_index.scss | 1 - .../management/roles/edit_role/_index.scss | 3 -- .../edit_role/collapsible_panel/_index.scss | 1 - ...ible_panel.scss => collapsible_panel.scss} | 0 .../collapsible_panel/collapsible_panel.tsx | 2 ++ .../roles/edit_role/privileges/_index.scss | 2 -- .../edit_role/privileges/kibana/_index.scss | 2 -- .../kibana/feature_table/_index.scss | 1 - ...ileges.scss => change_all_privileges.scss} | 0 .../feature_table/change_all_privileges.tsx | 3 ++ .../feature_table_cell.scss} | 0 .../feature_table_cell/feature_table_cell.tsx | 2 ++ .../space_aware_privilege_section/_index.scss | 1 - .../_privilege_matrix.scss | 14 -------- .../privilege_space_table.scss | 3 ++ .../privilege_space_table.tsx | 3 ++ .../edit_role/spaces_popover_list/_index.scss | 1 - ...ver_list.scss => spaces_popover_list.scss} | 0 .../spaces_popover_list.tsx | 2 ++ .../management/roles/roles_management_app.tsx | 32 ++++++++++++------- .../public/management/users/_index.scss | 1 - .../management/users/edit_user/_index.scss | 1 - ...dit_user_page.scss => edit_user_page.scss} | 2 +- .../users/edit_user/edit_user_page.tsx | 3 ++ .../management/users/users_management_app.tsx | 19 ++++++++--- 43 files changed, 89 insertions(+), 70 deletions(-) delete mode 100644 x-pack/plugins/security/public/authentication/access_agreement/_index.scss rename x-pack/plugins/security/public/authentication/access_agreement/{_access_agreement_page.scss => access_agreement_page.scss} (100%) rename x-pack/plugins/security/public/authentication/components/authentication_state_page/{_authentication_state_page.scss => authentication_state_page.scss} (100%) rename x-pack/plugins/security/public/authentication/login/{_login_page.scss => login_page.scss} (100%) delete mode 100644 x-pack/plugins/security/public/index.scss delete mode 100644 x-pack/plugins/security/public/management/_index.scss delete mode 100644 x-pack/plugins/security/public/management/role_mappings/_index.scss delete mode 100644 x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/_index.scss delete mode 100644 x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/_index.scss rename x-pack/plugins/security/public/management/role_mappings/edit_role_mapping/rule_editor_panel/{_rule_editor_group.scss => rule_group_editor.scss} (100%) delete mode 100644 x-pack/plugins/security/public/management/roles/_index.scss delete mode 100644 x-pack/plugins/security/public/management/roles/edit_role/_index.scss delete mode 100644 x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/_index.scss rename x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/{_collapsible_panel.scss => collapsible_panel.scss} (100%) delete mode 100644 x-pack/plugins/security/public/management/roles/edit_role/privileges/_index.scss delete mode 100644 x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/_index.scss delete mode 100644 x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/_index.scss rename x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/{_change_all_privileges.scss => change_all_privileges.scss} (100%) rename x-pack/plugins/security/public/management/roles/edit_role/privileges/{_privilege_feature_icon.scss => kibana/feature_table_cell/feature_table_cell.scss} (100%) delete mode 100644 x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/_index.scss delete mode 100644 x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/_privilege_matrix.scss create mode 100644 x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.scss delete mode 100644 x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/_index.scss rename x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/{_spaces_popover_list.scss => spaces_popover_list.scss} (100%) delete mode 100644 x-pack/plugins/security/public/management/users/_index.scss delete mode 100644 x-pack/plugins/security/public/management/users/edit_user/_index.scss rename x-pack/plugins/security/public/management/users/edit_user/{_edit_user_page.scss => edit_user_page.scss} (76%) diff --git a/x-pack/plugins/security/public/account_management/account_management_app.ts b/x-pack/plugins/security/public/account_management/account_management_app.ts index cd3ef34858b19c..41567a04fe0302 100644 --- a/x-pack/plugins/security/public/account_management/account_management_app.ts +++ b/x-pack/plugins/security/public/account_management/account_management_app.ts @@ -7,7 +7,6 @@ import { i18n } from '@kbn/i18n'; import { StartServicesAccessor, ApplicationSetup, AppMountParameters } from 'src/core/public'; import { AuthenticationServiceSetup } from '../authentication'; -import { UserAPIClient } from '../management'; interface CreateDeps { application: ApplicationSetup; @@ -28,9 +27,14 @@ export const accountManagementApp = Object.freeze({ navLinkStatus: 3, appRoute: '/security/account', async mount({ element }: AppMountParameters) { - const [[coreStart], { renderAccountManagementPage }] = await Promise.all([ + const [ + [coreStart], + { renderAccountManagementPage }, + { UserAPIClient }, + ] = await Promise.all([ getStartServices(), import('./account_management_page'), + import('../management'), ]); coreStart.chrome.setBreadcrumbs([{ text: title }]); diff --git a/x-pack/plugins/security/public/authentication/access_agreement/_index.scss b/x-pack/plugins/security/public/authentication/access_agreement/_index.scss deleted file mode 100644 index dbab8347b096f1..00000000000000 --- a/x-pack/plugins/security/public/authentication/access_agreement/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './access_agreement_page'; diff --git a/x-pack/plugins/security/public/authentication/access_agreement/_access_agreement_page.scss b/x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.scss similarity index 100% rename from x-pack/plugins/security/public/authentication/access_agreement/_access_agreement_page.scss rename to x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.scss diff --git a/x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.tsx b/x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.tsx index 0315e229c678b9..a34dcb18d2b9cc 100644 --- a/x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.tsx +++ b/x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import './_index.scss'; +import './access_agreement_page.scss'; import React, { FormEvent, MouseEvent, useCallback, useEffect, useState } from 'react'; import ReactDOM from 'react-dom'; diff --git a/x-pack/plugins/security/public/authentication/components/authentication_state_page/_authentication_state_page.scss b/x-pack/plugins/security/public/authentication/components/authentication_state_page/authentication_state_page.scss similarity index 100% rename from x-pack/plugins/security/public/authentication/components/authentication_state_page/_authentication_state_page.scss rename to x-pack/plugins/security/public/authentication/components/authentication_state_page/authentication_state_page.scss diff --git a/x-pack/plugins/security/public/authentication/components/authentication_state_page/authentication_state_page.tsx b/x-pack/plugins/security/public/authentication/components/authentication_state_page/authentication_state_page.tsx index 7567f455bcca67..35be650d127fb7 100644 --- a/x-pack/plugins/security/public/authentication/components/authentication_state_page/authentication_state_page.tsx +++ b/x-pack/plugins/security/public/authentication/components/authentication_state_page/authentication_state_page.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import './_authentication_state_page.scss'; +import './authentication_state_page.scss'; import { EuiIcon, EuiSpacer, EuiTitle } from '@elastic/eui'; import React from 'react'; diff --git a/x-pack/plugins/security/public/authentication/login/_login_page.scss b/x-pack/plugins/security/public/authentication/login/login_page.scss similarity index 100% rename from x-pack/plugins/security/public/authentication/login/_login_page.scss rename to x-pack/plugins/security/public/authentication/login/login_page.scss diff --git a/x-pack/plugins/security/public/authentication/login/login_page.tsx b/x-pack/plugins/security/public/authentication/login/login_page.tsx index b7ac70f2aaf89e..d24a301ed24ec7 100644 --- a/x-pack/plugins/security/public/authentication/login/login_page.tsx +++ b/x-pack/plugins/security/public/authentication/login/login_page.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import './_login_page.scss'; +import './login_page.scss'; import React, { Component } from 'react'; import ReactDOM from 'react-dom'; diff --git a/x-pack/plugins/security/public/index.scss b/x-pack/plugins/security/public/index.scss deleted file mode 100644 index 1bdb8cc178fdf8..00000000000000 --- a/x-pack/plugins/security/public/index.scss +++ /dev/null @@ -1,4 +0,0 @@ -$secFormWidth: 460px; - -// Management styles -@import './management/index'; diff --git a/x-pack/plugins/security/public/index.ts b/x-pack/plugins/security/public/index.ts index fc4e158652a0ae..8016c942240601 100644 --- a/x-pack/plugins/security/public/index.ts +++ b/x-pack/plugins/security/public/index.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import './index.scss'; import { PluginInitializer, PluginInitializerContext } from 'src/core/public'; import { SecurityPlugin, diff --git a/x-pack/plugins/security/public/management/_index.scss b/x-pack/plugins/security/public/management/_index.scss deleted file mode 100644 index 5d419b53230799..00000000000000 --- a/x-pack/plugins/security/public/management/_index.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import './roles/index'; -@import './users/index'; -@import './role_mappings/index'; diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx index 272fc9cfc2fe6a..b9ec5b35b3f9df 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx @@ -10,8 +10,6 @@ import { i18n } from '@kbn/i18n'; import { StartServicesAccessor } from 'src/core/public'; import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public'; import { PluginStartDependencies } from '../../plugin'; -import { APIKeysGridPage } from './api_keys_grid'; -import { APIKeysAPIClient } from './api_keys_api_client'; import { DocumentationLinksService } from './documentation_links'; interface CreateParams { @@ -28,7 +26,6 @@ export const apiKeysManagementApp = Object.freeze({ defaultMessage: 'API Keys', }), async mount({ basePath, element, setBreadcrumbs }) { - const [{ docLinks, http, notifications, i18n: i18nStart }] = await getStartServices(); setBreadcrumbs([ { text: i18n.translate('xpack.security.apiKeys.breadcrumb', { @@ -38,6 +35,16 @@ export const apiKeysManagementApp = Object.freeze({ }, ]); + const [ + [{ docLinks, http, notifications, i18n: i18nStart }], + { APIKeysGridPage }, + { APIKeysAPIClient }, + ] = await Promise.all([ + getStartServices(), + import('./api_keys_grid'), + import('./api_keys_api_client'), + ]); + render( ; @@ -31,7 +27,6 @@ export const roleMappingsManagementApp = Object.freeze({ defaultMessage: 'Role Mappings', }), async mount({ basePath, element, setBreadcrumbs }) { - const [{ docLinks, http, notifications, i18n: i18nStart }] = await getStartServices(); const roleMappingsBreadcrumbs = [ { text: i18n.translate('xpack.security.roleMapping.breadcrumb', { @@ -41,6 +36,20 @@ export const roleMappingsManagementApp = Object.freeze({ }, ]; + const [ + [{ docLinks, http, notifications, i18n: i18nStart }], + { RoleMappingsGridPage }, + { EditRoleMappingPage }, + { RoleMappingsAPIClient }, + { RolesAPIClient }, + ] = await Promise.all([ + getStartServices(), + import('./role_mappings_grid'), + import('./edit_role_mapping'), + import('./role_mappings_api_client'), + import('../roles'), + ]); + const roleMappingsAPIClient = new RoleMappingsAPIClient(http); const dockLinksService = new DocumentationLinksService(docLinks); const RoleMappingsGridPageWithBreadcrumbs = () => { diff --git a/x-pack/plugins/security/public/management/roles/_index.scss b/x-pack/plugins/security/public/management/roles/_index.scss deleted file mode 100644 index 5256c79f01f10f..00000000000000 --- a/x-pack/plugins/security/public/management/roles/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './edit_role/index'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/_index.scss b/x-pack/plugins/security/public/management/roles/edit_role/_index.scss deleted file mode 100644 index 0153b1734ceba0..00000000000000 --- a/x-pack/plugins/security/public/management/roles/edit_role/_index.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import './collapsible_panel/index'; -@import './spaces_popover_list/index'; -@import './privileges/index'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/_index.scss b/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/_index.scss deleted file mode 100644 index c0f4f8ab9a8701..00000000000000 --- a/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './collapsible_panel'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/_collapsible_panel.scss b/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/collapsible_panel.scss similarity index 100% rename from x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/_collapsible_panel.scss rename to x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/collapsible_panel.scss diff --git a/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/collapsible_panel.tsx b/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/collapsible_panel.tsx index 01af7cb4509f64..eb1417600e19b5 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/collapsible_panel.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/collapsible_panel/collapsible_panel.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './collapsible_panel.scss'; + import { EuiFlexGroup, EuiFlexItem, diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/_index.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/_index.scss deleted file mode 100644 index a1a9d038065e61..00000000000000 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/_index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import './privilege_feature_icon'; -@import './kibana/index'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/_index.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/_index.scss deleted file mode 100644 index 19547c0e1953e0..00000000000000 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/_index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import './feature_table/index'; -@import './space_aware_privilege_section/index'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/_index.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/_index.scss deleted file mode 100644 index 6a96553742819f..00000000000000 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './change_all_privileges'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/_change_all_privileges.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.scss similarity index 100% rename from x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/_change_all_privileges.scss rename to x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.scss diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.tsx index 2083778e539980..5d7b13acf79da6 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.tsx @@ -3,6 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import './change_all_privileges.scss'; + import { EuiContextMenuItem, EuiContextMenuPanel, EuiLink, EuiPopover } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import _ from 'lodash'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/_privilege_feature_icon.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss similarity index 100% rename from x-pack/plugins/security/public/management/roles/edit_role/privileges/_privilege_feature_icon.scss rename to x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.scss diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx index 9e4a3a8a99b565..77445952f3d692 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table_cell/feature_table_cell.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './feature_table_cell.scss'; + import React from 'react'; import { EuiText, EuiIconTip, EuiIcon, IconType } from '@elastic/eui'; import { SecuredFeature } from '../../../../model'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/_index.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/_index.scss deleted file mode 100644 index 3f40f21e102a1d..00000000000000 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './privilege_matrix'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/_privilege_matrix.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/_privilege_matrix.scss deleted file mode 100644 index 8f47727fdf8d62..00000000000000 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/_privilege_matrix.scss +++ /dev/null @@ -1,14 +0,0 @@ -/** - * 1. Allow table to scroll both directions - */ - -.secPrivilegeMatrix__modal, -.secPrivilegeMatrix__modal .euiModal__flex { - overflow: hidden; /* 1 */ -} - -.secPrivilegeMatrix__row--isBasePrivilege, -.secPrivilegeMatrix__cell--isGlobalPrivilege, -.secPrivilegeTable__row--isGlobalSpace { - background-color: $euiColorLightestShade; -} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.scss b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.scss new file mode 100644 index 00000000000000..8e2a3b0512afbf --- /dev/null +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.scss @@ -0,0 +1,3 @@ +.secPrivilegeTable__row--isGlobalSpace { + background-color: $euiColorLightestShade; +} diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx index ccb5398a11b236..30a275876fdc79 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx @@ -3,6 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import './privilege_space_table.scss'; + import { EuiBadge, EuiBadgeProps, diff --git a/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/_index.scss b/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/_index.scss deleted file mode 100644 index b40a32cb8df96b..00000000000000 --- a/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './spaces_popover_list'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/_spaces_popover_list.scss b/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.scss similarity index 100% rename from x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/_spaces_popover_list.scss rename to x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.scss diff --git a/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.tsx b/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.tsx index 92e42ec811afce..63ee311f3155ed 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/spaces_popover_list/spaces_popover_list.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './spaces_popover_list.scss'; + import { EuiButtonEmpty, EuiContextMenuItem, diff --git a/x-pack/plugins/security/public/management/roles/roles_management_app.tsx b/x-pack/plugins/security/public/management/roles/roles_management_app.tsx index e1a10fdc2b8c33..9aaa3b47f3b193 100644 --- a/x-pack/plugins/security/public/management/roles/roles_management_app.tsx +++ b/x-pack/plugins/security/public/management/roles/roles_management_app.tsx @@ -12,13 +12,7 @@ import { StartServicesAccessor, FatalErrorsSetup } from 'src/core/public'; import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public'; import { SecurityLicense } from '../../../common/licensing'; import { PluginStartDependencies } from '../../plugin'; -import { UserAPIClient } from '../users'; -import { RolesAPIClient } from './roles_api_client'; -import { RolesGridPage } from './roles_grid'; -import { EditRolePage } from './edit_role'; import { DocumentationLinksService } from './documentation_links'; -import { IndicesAPIClient } from './indices_api_client'; -import { PrivilegesAPIClient } from './privileges_api_client'; interface CreateParams { fatalErrors: FatalErrorsSetup; @@ -34,11 +28,6 @@ export const rolesManagementApp = Object.freeze({ order: 20, title: i18n.translate('xpack.security.management.rolesTitle', { defaultMessage: 'Roles' }), async mount({ basePath, element, setBreadcrumbs }) { - const [ - { application, docLinks, http, i18n: i18nStart, injectedMetadata, notifications }, - { data, features }, - ] = await getStartServices(); - const rolesBreadcrumbs = [ { text: i18n.translate('xpack.security.roles.breadcrumb', { defaultMessage: 'Roles' }), @@ -46,6 +35,27 @@ export const rolesManagementApp = Object.freeze({ }, ]; + const [ + [ + { application, docLinks, http, i18n: i18nStart, injectedMetadata, notifications }, + { data, features }, + ], + { RolesGridPage }, + { EditRolePage }, + { RolesAPIClient }, + { IndicesAPIClient }, + { PrivilegesAPIClient }, + { UserAPIClient }, + ] = await Promise.all([ + getStartServices(), + import('./roles_grid'), + import('./edit_role'), + import('./roles_api_client'), + import('./indices_api_client'), + import('./privileges_api_client'), + import('../users'), + ]); + const rolesAPIClient = new RolesAPIClient(http); const RolesGridPageWithBreadcrumbs = () => { setBreadcrumbs(rolesBreadcrumbs); diff --git a/x-pack/plugins/security/public/management/users/_index.scss b/x-pack/plugins/security/public/management/users/_index.scss deleted file mode 100644 index 35df0c1b965837..00000000000000 --- a/x-pack/plugins/security/public/management/users/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './edit_user/index'; diff --git a/x-pack/plugins/security/public/management/users/edit_user/_index.scss b/x-pack/plugins/security/public/management/users/edit_user/_index.scss deleted file mode 100644 index 734ba7882ba72c..00000000000000 --- a/x-pack/plugins/security/public/management/users/edit_user/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './edit_user_page'; diff --git a/x-pack/plugins/security/public/management/users/edit_user/_edit_user_page.scss b/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.scss similarity index 76% rename from x-pack/plugins/security/public/management/users/edit_user/_edit_user_page.scss rename to x-pack/plugins/security/public/management/users/edit_user/edit_user_page.scss index 7b24b74aceba0c..727fac4782752d 100644 --- a/x-pack/plugins/security/public/management/users/edit_user/_edit_user_page.scss +++ b/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.scss @@ -1,5 +1,5 @@ .secUsersEditPage__content { - max-width: $secFormWidth; + max-width: 460px; margin-left: auto; margin-right: auto; flex-grow: 0; diff --git a/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.tsx b/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.tsx index 6417ce81b647d5..1c8130029bb501 100644 --- a/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.tsx +++ b/x-pack/plugins/security/public/management/users/edit_user/edit_user_page.tsx @@ -3,6 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import './edit_user_page.scss'; + import { get } from 'lodash'; import React, { Component, Fragment, ChangeEvent } from 'react'; import { diff --git a/x-pack/plugins/security/public/management/users/users_management_app.tsx b/x-pack/plugins/security/public/management/users/users_management_app.tsx index 82a2b8d2a98ada..9d337c1508ad48 100644 --- a/x-pack/plugins/security/public/management/users/users_management_app.tsx +++ b/x-pack/plugins/security/public/management/users/users_management_app.tsx @@ -12,10 +12,6 @@ import { StartServicesAccessor } from 'src/core/public'; import { RegisterManagementAppArgs } from '../../../../../../src/plugins/management/public'; import { AuthenticationServiceSetup } from '../../authentication'; import { PluginStartDependencies } from '../../plugin'; -import { RolesAPIClient } from '../roles'; -import { UserAPIClient } from './user_api_client'; -import { UsersGridPage } from './users_grid'; -import { EditUserPage } from './edit_user'; interface CreateParams { authc: AuthenticationServiceSetup; @@ -30,7 +26,6 @@ export const usersManagementApp = Object.freeze({ order: 10, title: i18n.translate('xpack.security.management.usersTitle', { defaultMessage: 'Users' }), async mount({ basePath, element, setBreadcrumbs }) { - const [{ http, notifications, i18n: i18nStart }] = await getStartServices(); const usersBreadcrumbs = [ { text: i18n.translate('xpack.security.users.breadcrumb', { defaultMessage: 'Users' }), @@ -38,6 +33,20 @@ export const usersManagementApp = Object.freeze({ }, ]; + const [ + [{ http, notifications, i18n: i18nStart }], + { UsersGridPage }, + { EditUserPage }, + { UserAPIClient }, + { RolesAPIClient }, + ] = await Promise.all([ + getStartServices(), + import('./users_grid'), + import('./edit_user'), + import('./user_api_client'), + import('../roles'), + ]); + const userAPIClient = new UserAPIClient(http); const rolesAPIClient = new RolesAPIClient(http); const UsersGridPageWithBreadcrumbs = () => { From 5082ff3252f60f2ed6f4ed3789a1f142e1667e1f Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Wed, 29 Apr 2020 18:43:15 +0200 Subject: [PATCH 17/26] use cache busting for KP bundles (#64414) * convert into TS * load plugin scripts in html body * use buildNum as a unique Id for cache busting * add tests for caching * fix tests * remove the last TODO. url should be inlined with assetss server * this logic handled by publicPathMap on the client * cache kbn-shared-deps as well * attempt to fix karma tests * always run file through replace stream * place buildHash at begining of path, include all static files * update bundles_route tests to inject buildNum everywhere * fix karma config to point to right prefix * use isDist naming throughout * explain magic number with variables * restore replacePublicPath option from #64226 * replace one more instance of replacePublicPath * use promisify instead of bluebird + non-null assertions * remove one more magic number Co-authored-by: spalger Co-authored-by: Elastic Machine --- src/legacy/ui/ui_render/ui_render_mixin.js | 15 ++- .../bundles_route/__tests__/bundles_route.js | 119 +++++++++++++++--- src/optimize/bundles_route/bundles_route.ts | 35 ++++-- .../bundles_route/dynamic_asset_response.ts | 25 +++- .../bundles_route/proxy_bundles_route.ts | 16 ++- src/optimize/np_ui_plugin_public_dirs.ts | 1 - src/optimize/optimize_mixin.ts | 2 + src/optimize/watch/optmzr_role.js | 3 +- src/optimize/watch/proxy_role.js | 1 + src/optimize/watch/watch_optimizer.js | 3 +- src/optimize/watch/watch_server.js | 10 +- tasks/config/karma.js | 26 ++-- 12 files changed, 195 insertions(+), 61 deletions(-) diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index d42d6d556b37be..692b787ccf4052 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -96,9 +96,12 @@ export function uiRenderMixin(kbnServer, server, config) { ? await uiSettings.get('theme:darkMode') : false; + const buildHash = server.newPlatform.env.packageInfo.buildNum; const basePath = config.get('server.basePath'); - const regularBundlePath = `${basePath}/bundles`; - const dllBundlePath = `${basePath}/built_assets/dlls`; + + const regularBundlePath = `${basePath}/${buildHash}/bundles`; + const dllBundlePath = `${basePath}/${buildHash}/built_assets/dlls`; + const dllStyleChunks = DllCompiler.getRawDllConfig().chunks.map( chunk => `${dllBundlePath}/vendors${chunk}.style.dll.css` ); @@ -108,15 +111,15 @@ export function uiRenderMixin(kbnServer, server, config) { const styleSheetPaths = [ ...(isCore ? [] : dllStyleChunks), - `${basePath}/bundles/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`, + `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`, ...(darkMode ? [ - `${basePath}/bundles/kbn-ui-shared-deps/${UiSharedDeps.darkCssDistFilename}`, + `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.darkCssDistFilename}`, `${basePath}/node_modules/@kbn/ui-framework/dist/kui_dark.css`, `${regularBundlePath}/dark_theme.style.css`, ] : [ - `${basePath}/bundles/kbn-ui-shared-deps/${UiSharedDeps.lightCssDistFilename}`, + `${regularBundlePath}/kbn-ui-shared-deps/${UiSharedDeps.lightCssDistFilename}`, `${basePath}/node_modules/@kbn/ui-framework/dist/kui_light.css`, `${regularBundlePath}/light_theme.style.css`, ]), @@ -131,7 +134,7 @@ export function uiRenderMixin(kbnServer, server, config) { ) .map(path => path.localPath.endsWith('.scss') - ? `${basePath}/built_assets/css/${path.publicPath}` + ? `${basePath}/${buildHash}/built_assets/css/${path.publicPath}` : `${basePath}/${path.publicPath}` ) .reverse(), diff --git a/src/optimize/bundles_route/__tests__/bundles_route.js b/src/optimize/bundles_route/__tests__/bundles_route.js index 0b2aeda11fb0e4..902fa59b205698 100644 --- a/src/optimize/bundles_route/__tests__/bundles_route.js +++ b/src/optimize/bundles_route/__tests__/bundles_route.js @@ -32,6 +32,7 @@ import { PUBLIC_PATH_PLACEHOLDER } from '../../public_path_placeholder'; const chance = new Chance(); const outputFixture = resolve(__dirname, './fixtures/output'); +const pluginNoPlaceholderFixture = resolve(__dirname, './fixtures/plugin/no_placeholder'); const randomWordsCache = new Set(); const uniqueRandomWord = () => { @@ -58,6 +59,9 @@ describe('optimizer/bundle route', () => { dllBundlesPath = outputFixture, basePublicPath = '', builtCssPath = outputFixture, + npUiPluginPublicDirs = [], + buildHash = '1234', + isDist = false, } = options; const server = new Hapi.Server(); @@ -69,6 +73,9 @@ describe('optimizer/bundle route', () => { dllBundlesPath, basePublicPath, builtCssPath, + npUiPluginPublicDirs, + buildHash, + isDist, }) ); @@ -158,7 +165,7 @@ describe('optimizer/bundle route', () => { it('responds with exact file data', async () => { const server = createServer(); const response = await server.inject({ - url: '/bundles/image.png', + url: '/1234/bundles/image.png', }); expect(response.statusCode).to.be(200); @@ -173,7 +180,7 @@ describe('optimizer/bundle route', () => { it('responds with no content-length and exact file data', async () => { const server = createServer(); const response = await server.inject({ - url: '/bundles/no_placeholder.js', + url: '/1234/bundles/no_placeholder.js', }); expect(response.statusCode).to.be(200); @@ -187,12 +194,12 @@ describe('optimizer/bundle route', () => { }); describe('js file with placeholder', () => { - it('responds with no content-length and modified file data', async () => { + it('responds with no content-length and modifiedfile data ', async () => { const basePublicPath = `/${uniqueRandomWord()}`; const server = createServer({ basePublicPath }); const response = await server.inject({ - url: '/bundles/with_placeholder.js', + url: '/1234/bundles/with_placeholder.js', }); expect(response.statusCode).to.be(200); @@ -204,7 +211,7 @@ describe('optimizer/bundle route', () => { ); expect(response.result.indexOf(source)).to.be(-1); expect(response.result).to.be( - replaceAll(source, PUBLIC_PATH_PLACEHOLDER, `${basePublicPath}/bundles/`) + replaceAll(source, PUBLIC_PATH_PLACEHOLDER, `${basePublicPath}/1234/bundles/`) ); }); }); @@ -213,7 +220,7 @@ describe('optimizer/bundle route', () => { it('responds with no content-length and exact file data', async () => { const server = createServer(); const response = await server.inject({ - url: '/bundles/no_placeholder.css', + url: '/1234/bundles/no_placeholder.css', }); expect(response.statusCode).to.be(200); @@ -231,7 +238,7 @@ describe('optimizer/bundle route', () => { const server = createServer({ basePublicPath }); const response = await server.inject({ - url: '/bundles/with_placeholder.css', + url: '/1234/bundles/with_placeholder.css', }); expect(response.statusCode).to.be(200); @@ -240,7 +247,7 @@ describe('optimizer/bundle route', () => { expect(response.headers).to.have.property('content-type', 'text/css; charset=utf-8'); expect(response.result.indexOf(source)).to.be(-1); expect(response.result).to.be( - replaceAll(source, PUBLIC_PATH_PLACEHOLDER, `${basePublicPath}/bundles/`) + replaceAll(source, PUBLIC_PATH_PLACEHOLDER, `${basePublicPath}/1234/bundles/`) ); }); }); @@ -250,7 +257,7 @@ describe('optimizer/bundle route', () => { const server = createServer(); const response = await server.inject({ - url: '/bundles/../outside_output.js', + url: '/1234/bundles/../outside_output.js', }); expect(response.statusCode).to.be(404); @@ -267,7 +274,7 @@ describe('optimizer/bundle route', () => { const server = createServer(); const response = await server.inject({ - url: '/bundles/non_existent.js', + url: '/1234/bundles/non_existent.js', }); expect(response.statusCode).to.be(404); @@ -286,7 +293,7 @@ describe('optimizer/bundle route', () => { }); const response = await server.inject({ - url: '/bundles/with_placeholder.js', + url: '/1234/bundles/with_placeholder.js', }); expect(response.statusCode).to.be(404); @@ -306,7 +313,7 @@ describe('optimizer/bundle route', () => { sinon.assert.notCalled(createHash); const resp1 = await server.inject({ - url: '/bundles/no_placeholder.js', + url: '/1234/bundles/no_placeholder.js', }); sinon.assert.calledOnce(createHash); @@ -314,23 +321,23 @@ describe('optimizer/bundle route', () => { expect(resp1.statusCode).to.be(200); const resp2 = await server.inject({ - url: '/bundles/no_placeholder.js', + url: '/1234/bundles/no_placeholder.js', }); sinon.assert.notCalled(createHash); expect(resp2.statusCode).to.be(200); }); - it('is unique per basePublicPath although content is the same', async () => { + it('is unique per basePublicPath although content is the same (by default)', async () => { const basePublicPath1 = `/${uniqueRandomWord()}`; const basePublicPath2 = `/${uniqueRandomWord()}`; const [resp1, resp2] = await Promise.all([ createServer({ basePublicPath: basePublicPath1 }).inject({ - url: '/bundles/no_placeholder.js', + url: '/1234/bundles/no_placeholder.js', }), createServer({ basePublicPath: basePublicPath2 }).inject({ - url: '/bundles/no_placeholder.js', + url: '/1234/bundles/no_placeholder.js', }), ]); @@ -349,13 +356,13 @@ describe('optimizer/bundle route', () => { it('responds with 304 when etag and last modified are sent back', async () => { const server = createServer(); const resp = await server.inject({ - url: '/bundles/with_placeholder.js', + url: '/1234/bundles/with_placeholder.js', }); expect(resp.statusCode).to.be(200); const resp2 = await server.inject({ - url: '/bundles/with_placeholder.js', + url: '/1234/bundles/with_placeholder.js', headers: { 'if-modified-since': resp.headers['last-modified'], 'if-none-match': resp.headers.etag, @@ -366,4 +373,80 @@ describe('optimizer/bundle route', () => { expect(resp2.result).to.have.length(0); }); }); + + describe('kibana platform assets', () => { + describe('caching', () => { + describe('for non-distributable mode', () => { + it('uses "etag" header to invalidate cache', async () => { + const basePublicPath = `/${uniqueRandomWord()}`; + + const npUiPluginPublicDirs = [ + { + id: 'no_placeholder', + path: pluginNoPlaceholderFixture, + }, + ]; + const responce = await createServer({ basePublicPath, npUiPluginPublicDirs }).inject({ + url: '/1234/bundles/plugin/no_placeholder/no_placeholder.plugin.js', + }); + + expect(responce.statusCode).to.be(200); + + expect(responce.headers.etag).to.be.a('string'); + expect(responce.headers['cache-control']).to.be('must-revalidate'); + }); + + it('creates the same "etag" header for the same content with the same basePath', async () => { + const npUiPluginPublicDirs = [ + { + id: 'no_placeholder', + path: pluginNoPlaceholderFixture, + }, + ]; + const [resp1, resp2] = await Promise.all([ + createServer({ basePublicPath: '', npUiPluginPublicDirs }).inject({ + url: '/1234/bundles/plugin/no_placeholder/no_placeholder.plugin.js', + }), + createServer({ basePublicPath: '', npUiPluginPublicDirs }).inject({ + url: '/1234/bundles/plugin/no_placeholder/no_placeholder.plugin.js', + }), + ]); + + expect(resp1.statusCode).to.be(200); + expect(resp2.statusCode).to.be(200); + + expect(resp1.rawPayload).to.eql(resp2.rawPayload); + + expect(resp1.headers.etag).to.be.a('string'); + expect(resp2.headers.etag).to.be.a('string'); + expect(resp1.headers.etag).to.eql(resp2.headers.etag); + }); + }); + + describe('for distributable mode', () => { + it('commands to cache assets for each release for a year', async () => { + const basePublicPath = `/${uniqueRandomWord()}`; + + const npUiPluginPublicDirs = [ + { + id: 'no_placeholder', + path: pluginNoPlaceholderFixture, + }, + ]; + const responce = await createServer({ + basePublicPath, + npUiPluginPublicDirs, + isDist: true, + }).inject({ + url: '/1234/bundles/plugin/no_placeholder/no_placeholder.plugin.js', + }); + + expect(responce.statusCode).to.be(200); + + expect(responce.headers.etag).to.be(undefined); + expect(responce.headers['cache-control']).to.be('max-age=31536000'); + }); + }); + }); + }); }); diff --git a/src/optimize/bundles_route/bundles_route.ts b/src/optimize/bundles_route/bundles_route.ts index 5605ec5338969c..e9cfba0130d951 100644 --- a/src/optimize/bundles_route/bundles_route.ts +++ b/src/optimize/bundles_route/bundles_route.ts @@ -47,12 +47,16 @@ export function createBundlesRoute({ basePublicPath, builtCssPath, npUiPluginPublicDirs = [], + buildHash, + isDist = false, }: { regularBundlesPath: string; dllBundlesPath: string; basePublicPath: string; builtCssPath: string; npUiPluginPublicDirs?: NpUiPluginPublicDirs; + buildHash: string; + isDist?: boolean; }) { // rather than calculate the fileHash on every request, we // provide a cache object to `resolveDynamicAssetResponse()` that @@ -82,45 +86,51 @@ export function createBundlesRoute({ return [ buildRouteForBundles({ - publicPath: `${basePublicPath}/bundles/kbn-ui-shared-deps/`, - routePath: '/bundles/kbn-ui-shared-deps/', + publicPath: `${basePublicPath}/${buildHash}/bundles/kbn-ui-shared-deps/`, + routePath: `/${buildHash}/bundles/kbn-ui-shared-deps/`, bundlesPath: UiSharedDeps.distDir, fileHashCache, replacePublicPath: false, + isDist, }), ...npUiPluginPublicDirs.map(({ id, path }) => buildRouteForBundles({ - publicPath: `${basePublicPath}/bundles/plugin/${id}/`, - routePath: `/bundles/plugin/${id}/`, + publicPath: `${basePublicPath}/${buildHash}/bundles/plugin/${id}/`, + routePath: `/${buildHash}/bundles/plugin/${id}/`, bundlesPath: path, fileHashCache, replacePublicPath: false, + isDist, }) ), buildRouteForBundles({ - publicPath: `${basePublicPath}/bundles/core/`, - routePath: `/bundles/core/`, + publicPath: `${basePublicPath}/${buildHash}/bundles/core/`, + routePath: `/${buildHash}/bundles/core/`, bundlesPath: fromRoot(join('src', 'core', 'target', 'public')), fileHashCache, replacePublicPath: false, + isDist, }), buildRouteForBundles({ - publicPath: `${basePublicPath}/bundles/`, - routePath: '/bundles/', + publicPath: `${basePublicPath}/${buildHash}/bundles/`, + routePath: `/${buildHash}/bundles/`, bundlesPath: regularBundlesPath, fileHashCache, + isDist, }), buildRouteForBundles({ - publicPath: `${basePublicPath}/built_assets/dlls/`, - routePath: '/built_assets/dlls/', + publicPath: `${basePublicPath}/${buildHash}/built_assets/dlls/`, + routePath: `/${buildHash}/built_assets/dlls/`, bundlesPath: dllBundlesPath, fileHashCache, + isDist, }), buildRouteForBundles({ publicPath: `${basePublicPath}/`, - routePath: '/built_assets/css/', + routePath: `/${buildHash}/built_assets/css/`, bundlesPath: builtCssPath, fileHashCache, + isDist, }), ]; } @@ -131,12 +141,14 @@ function buildRouteForBundles({ bundlesPath, fileHashCache, replacePublicPath = true, + isDist, }: { publicPath: string; routePath: string; bundlesPath: string; fileHashCache: FileHashCache; replacePublicPath?: boolean; + isDist: boolean; }) { return { method: 'GET', @@ -159,6 +171,7 @@ function buildRouteForBundles({ fileHashCache, publicPath, replacePublicPath, + isDist, }); }, }, diff --git a/src/optimize/bundles_route/dynamic_asset_response.ts b/src/optimize/bundles_route/dynamic_asset_response.ts index bebc062ee949df..a020c6935eeecf 100644 --- a/src/optimize/bundles_route/dynamic_asset_response.ts +++ b/src/optimize/bundles_route/dynamic_asset_response.ts @@ -17,8 +17,8 @@ * under the License. */ -import { resolve } from 'path'; import Fs from 'fs'; +import { resolve } from 'path'; import { promisify } from 'util'; import Boom from 'boom'; @@ -26,8 +26,13 @@ import Hapi from 'hapi'; import { FileHashCache } from './file_hash_cache'; import { getFileHash } from './file_hash'; +// @ts-ignore import { replacePlaceholder } from '../public_path_placeholder'; +const MINUTE = 60; +const HOUR = 60 * MINUTE; +const DAY = 24 * HOUR; + const asyncOpen = promisify(Fs.open); const asyncClose = promisify(Fs.close); const asyncFstat = promisify(Fs.fstat); @@ -58,6 +63,7 @@ export async function createDynamicAssetResponse({ publicPath, fileHashCache, replacePublicPath, + isDist, }: { request: Hapi.Request; h: Hapi.ResponseToolkit; @@ -65,6 +71,7 @@ export async function createDynamicAssetResponse({ publicPath: string; fileHashCache: FileHashCache; replacePublicPath: boolean; + isDist: boolean; }) { let fd: number | undefined; @@ -82,7 +89,7 @@ export async function createDynamicAssetResponse({ fd = await asyncOpen(path, 'r'); const stat = await asyncFstat(fd); - const hash = await getFileHash(fileHashCache, path, stat, fd); + const hash = isDist ? undefined : await getFileHash(fileHashCache, path, stat, fd); const read = Fs.createReadStream(null as any, { fd, @@ -92,15 +99,21 @@ export async function createDynamicAssetResponse({ fd = undefined; // read stream is now responsible for fd const content = replacePublicPath ? replacePlaceholder(read, publicPath) : read; - const etag = replacePublicPath ? `${hash}-${publicPath}` : hash; - return h + const response = h .response(content) .takeover() .code(200) - .etag(etag) - .header('cache-control', 'must-revalidate') .type(request.server.mime.path(path).type); + + if (isDist) { + response.header('cache-control', `max-age=${365 * DAY}`); + } else { + response.etag(`${hash}-${publicPath}`); + response.header('cache-control', 'must-revalidate'); + } + + return response; } catch (error) { if (fd) { try { diff --git a/src/optimize/bundles_route/proxy_bundles_route.ts b/src/optimize/bundles_route/proxy_bundles_route.ts index 97616f7041f1c8..1d189054324a1c 100644 --- a/src/optimize/bundles_route/proxy_bundles_route.ts +++ b/src/optimize/bundles_route/proxy_bundles_route.ts @@ -17,11 +17,19 @@ * under the License. */ -export function createProxyBundlesRoute({ host, port }: { host: string; port: number }) { +export function createProxyBundlesRoute({ + host, + port, + buildHash, +}: { + host: string; + port: number; + buildHash: string; +}) { return [ - buildProxyRouteForBundles('/bundles/', host, port), - buildProxyRouteForBundles('/built_assets/dlls/', host, port), - buildProxyRouteForBundles('/built_assets/css/', host, port), + buildProxyRouteForBundles(`/${buildHash}/bundles/`, host, port), + buildProxyRouteForBundles(`/${buildHash}/built_assets/dlls/`, host, port), + buildProxyRouteForBundles(`/${buildHash}/built_assets/css/`, host, port), ]; } diff --git a/src/optimize/np_ui_plugin_public_dirs.ts b/src/optimize/np_ui_plugin_public_dirs.ts index 268d9b1485dd8f..e7c3207948f6a3 100644 --- a/src/optimize/np_ui_plugin_public_dirs.ts +++ b/src/optimize/np_ui_plugin_public_dirs.ts @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - import KbnServer from '../legacy/server/kbn_server'; export type NpUiPluginPublicDirs = Array<{ diff --git a/src/optimize/optimize_mixin.ts b/src/optimize/optimize_mixin.ts index 5abe43ca1577ad..9a3f08e2f667eb 100644 --- a/src/optimize/optimize_mixin.ts +++ b/src/optimize/optimize_mixin.ts @@ -57,6 +57,8 @@ export const optimizeMixin = async ( basePublicPath: config.get('server.basePath'), builtCssPath: fromRoot('built_assets/css'), npUiPluginPublicDirs: getNpUiPluginPublicDirs(kbnServer), + buildHash: kbnServer.newPlatform.env.packageInfo.buildNum.toString(), + isDist: kbnServer.newPlatform.env.packageInfo.dist, }) ); diff --git a/src/optimize/watch/optmzr_role.js b/src/optimize/watch/optmzr_role.js index a31ef7229e5da3..1f6107996277cb 100644 --- a/src/optimize/watch/optmzr_role.js +++ b/src/optimize/watch/optmzr_role.js @@ -49,7 +49,8 @@ export default async (kbnServer, kibanaHapiServer, config) => { config.get('optimize.watchPort'), config.get('server.basePath'), watchOptimizer, - getNpUiPluginPublicDirs(kbnServer) + getNpUiPluginPublicDirs(kbnServer), + kbnServer.newPlatform.env.packageInfo.buildNum.toString() ); watchOptimizer.status$.subscribe({ diff --git a/src/optimize/watch/proxy_role.js b/src/optimize/watch/proxy_role.js index 6093658ae1a2d8..0f6f3b2d4b6226 100644 --- a/src/optimize/watch/proxy_role.js +++ b/src/optimize/watch/proxy_role.js @@ -26,6 +26,7 @@ export default (kbnServer, server, config) => { createProxyBundlesRoute({ host: config.get('optimize.watchHost'), port: config.get('optimize.watchPort'), + buildHash: kbnServer.newPlatform.env.packageInfo.buildNum.toString(), }) ); diff --git a/src/optimize/watch/watch_optimizer.js b/src/optimize/watch/watch_optimizer.js index 6c20f21c7768e9..cdff57a00c2e09 100644 --- a/src/optimize/watch/watch_optimizer.js +++ b/src/optimize/watch/watch_optimizer.js @@ -106,7 +106,7 @@ export default class WatchOptimizer extends BaseOptimizer { }); } - bindToServer(server, basePath, npUiPluginPublicDirs) { + bindToServer(server, basePath, npUiPluginPublicDirs, buildHash) { // pause all requests received while the compiler is running // and continue once an outcome is reached (aborting the request // with an error if it was a failure). @@ -118,6 +118,7 @@ export default class WatchOptimizer extends BaseOptimizer { server.route( createBundlesRoute({ npUiPluginPublicDirs: npUiPluginPublicDirs, + buildHash, regularBundlesPath: this.compiler.outputPath, dllBundlesPath: DllCompiler.getRawDllConfig().outputPath, basePublicPath: basePath, diff --git a/src/optimize/watch/watch_server.js b/src/optimize/watch/watch_server.js index 74a96dc8aea6e6..81e04a5b83956a 100644 --- a/src/optimize/watch/watch_server.js +++ b/src/optimize/watch/watch_server.js @@ -21,10 +21,11 @@ import { Server } from 'hapi'; import { registerHapiPlugins } from '../../legacy/server/http/register_hapi_plugins'; export default class WatchServer { - constructor(host, port, basePath, optimizer, npUiPluginPublicDirs) { + constructor(host, port, basePath, optimizer, npUiPluginPublicDirs, buildHash) { this.basePath = basePath; this.optimizer = optimizer; this.npUiPluginPublicDirs = npUiPluginPublicDirs; + this.buildHash = buildHash; this.server = new Server({ host: host, port: port, @@ -35,7 +36,12 @@ export default class WatchServer { async init() { await this.optimizer.init(); - this.optimizer.bindToServer(this.server, this.basePath, this.npUiPluginPublicDirs); + this.optimizer.bindToServer( + this.server, + this.basePath, + this.npUiPluginPublicDirs, + this.buildHash + ); await this.server.start(); } } diff --git a/tasks/config/karma.js b/tasks/config/karma.js index 1ec7c831b48641..f87edbf04f220c 100644 --- a/tasks/config/karma.js +++ b/tasks/config/karma.js @@ -25,6 +25,7 @@ import { DllCompiler } from '../../src/optimize/dynamic_dll_plugin'; const TOTAL_CI_SHARDS = 4; const ROOT = dirname(require.resolve('../../package.json')); +const buildHash = String(Number.MAX_SAFE_INTEGER); module.exports = function(grunt) { function pickBrowser() { @@ -57,27 +58,30 @@ module.exports = function(grunt) { 'http://localhost:5610/test_bundle/karma/globals.js', ...UiSharedDeps.jsDepFilenames.map( - chunkFilename => `http://localhost:5610/bundles/kbn-ui-shared-deps/${chunkFilename}` + chunkFilename => + `http://localhost:5610/${buildHash}/bundles/kbn-ui-shared-deps/${chunkFilename}` ), - `http://localhost:5610/bundles/kbn-ui-shared-deps/${UiSharedDeps.jsFilename}`, + `http://localhost:5610/${buildHash}/bundles/kbn-ui-shared-deps/${UiSharedDeps.jsFilename}`, - 'http://localhost:5610/built_assets/dlls/vendors_runtime.bundle.dll.js', + `http://localhost:5610/${buildHash}/built_assets/dlls/vendors_runtime.bundle.dll.js`, ...DllCompiler.getRawDllConfig().chunks.map( - chunk => `http://localhost:5610/built_assets/dlls/vendors${chunk}.bundle.dll.js` + chunk => + `http://localhost:5610/${buildHash}/built_assets/dlls/vendors${chunk}.bundle.dll.js` ), shardNum === undefined - ? `http://localhost:5610/bundles/tests.bundle.js` - : `http://localhost:5610/bundles/tests.bundle.js?shards=${TOTAL_CI_SHARDS}&shard_num=${shardNum}`, + ? `http://localhost:5610/${buildHash}/bundles/tests.bundle.js` + : `http://localhost:5610/${buildHash}/bundles/tests.bundle.js?shards=${TOTAL_CI_SHARDS}&shard_num=${shardNum}`, - `http://localhost:5610/bundles/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`, + `http://localhost:5610/${buildHash}/bundles/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`, // this causes tilemap tests to fail, probably because the eui styles haven't been // included in the karma harness a long some time, if ever // `http://localhost:5610/bundles/kbn-ui-shared-deps/${UiSharedDeps.lightCssDistFilename}`, ...DllCompiler.getRawDllConfig().chunks.map( - chunk => `http://localhost:5610/built_assets/dlls/vendors${chunk}.style.dll.css` + chunk => + `http://localhost:5610/${buildHash}/built_assets/dlls/vendors${chunk}.style.dll.css` ), - 'http://localhost:5610/bundles/tests.style.css', + `http://localhost:5610/${buildHash}/bundles/tests.style.css`, ]; } @@ -127,9 +131,9 @@ module.exports = function(grunt) { proxies: { '/tests/': 'http://localhost:5610/tests/', - '/bundles/': 'http://localhost:5610/bundles/', - '/built_assets/dlls/': 'http://localhost:5610/built_assets/dlls/', '/test_bundle/': 'http://localhost:5610/test_bundle/', + [`/${buildHash}/bundles/`]: `http://localhost:5610/${buildHash}/bundles/`, + [`/${buildHash}/built_assets/dlls/`]: `http://localhost:5610/${buildHash}/built_assets/dlls/`, }, client: { From 0d4cfba4b44db847600cc6a34cb697deae7675a9 Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 29 Apr 2020 09:44:56 -0700 Subject: [PATCH 18/26] share single data plugin bundle (#64549) --- packages/kbn-optimizer/src/worker/webpack.config.ts | 11 +++-------- src/legacy/ui/ui_render/ui_render_mixin.js | 3 ++- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index 7411e2df1b613c..cc3fa8c2720ded 100644 --- a/packages/kbn-optimizer/src/worker/webpack.config.ts +++ b/packages/kbn-optimizer/src/worker/webpack.config.ts @@ -37,7 +37,7 @@ const ISTANBUL_PRESET_PATH = require.resolve('@kbn/babel-preset/istanbul_preset' const BABEL_PRESET_PATH = require.resolve('@kbn/babel-preset/webpack_preset'); const STATIC_BUNDLE_PLUGINS = [ - // { id: 'data', dirname: 'data' }, + { id: 'data', dirname: 'data' }, { id: 'kibanaReact', dirname: 'kibana_react' }, { id: 'kibanaUtils', dirname: 'kibana_utils' }, { id: 'esUiShared', dirname: 'es_ui_shared' }, @@ -60,13 +60,8 @@ function dynamicExternals(bundle: Bundle, context: string, request: string) { return; } - // don't allow any static bundle to rely on other static bundles - if (STATIC_BUNDLE_PLUGINS.some(p => bundle.id === p.id)) { - return; - } - - // ignore requests that don't include a /data/public, /kibana_react/public, or - // /kibana_utils/public segment as a cheap way to avoid doing path resolution + // ignore requests that don't include a /{dirname}/public for one of our + // "static" bundles as a cheap way to avoid doing path resolution // for paths that couldn't possibly resolve to what we're looking for const reqToStaticBundle = STATIC_BUNDLE_PLUGINS.some(p => request.includes(`/${p.dirname}/public`) diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index 692b787ccf4052..9b44395fa9c68a 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -145,8 +145,9 @@ export function uiRenderMixin(kbnServer, server, config) { // load these plugins first, they are "shared" and other bundles access their // public/index exports without considering topographic sorting by plugin deps (for now) 'kibanaUtils', - 'esUiShared', 'kibanaReact', + 'data', + 'esUiShared', ...kbnServer.newPlatform.__internals.uiPlugins.public.keys() ); From f8e01bd3a14f606c2086955539e588484b0ab379 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Wed, 29 Apr 2020 11:58:46 -0500 Subject: [PATCH 19/26] [SIEM][NP] Fixes bug in ML signals promotion (#64720) * Add set-value as an explicit dependency This is a more robust solution than lodash's set(). * Replace lodash.set() with set-value's equivalent * Rebuild renovate config We added set-value to our dependencies. Co-authored-by: Elastic Machine --- renovate.json5 | 8 ++++++++ x-pack/package.json | 2 ++ .../signals/bulk_create_ml_signals.ts | 10 +++++++--- yarn.lock | 12 ++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index ffa006264873d3..c0ddcaf4f23c8f 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -846,6 +846,14 @@ '@types/semver', ], }, + { + groupSlug: 'set-value', + groupName: 'set-value related packages', + packageNames: [ + 'set-value', + '@types/set-value', + ], + }, { groupSlug: 'sinon', groupName: 'sinon related packages', diff --git a/x-pack/package.json b/x-pack/package.json index 604889c6094b9c..dcc9b8c61cb960 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -105,6 +105,7 @@ "@types/recompose": "^0.30.6", "@types/reduce-reducers": "^1.0.0", "@types/redux-actions": "^2.6.1", + "@types/set-value": "^2.0.0", "@types/sinon": "^7.0.13", "@types/styled-components": "^4.4.2", "@types/supertest": "^2.0.5", @@ -344,6 +345,7 @@ "rison-node": "0.3.1", "rxjs": "^6.5.3", "semver": "5.7.0", + "set-value": "^3.0.2", "squel": "^5.13.0", "stats-lite": "^2.2.0", "style-it": "^2.1.3", diff --git a/x-pack/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts b/x-pack/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts index d298f1cc7cbc66..a8cc6dc6804102 100644 --- a/x-pack/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts +++ b/x-pack/plugins/siem/server/lib/detection_engine/signals/bulk_create_ml_signals.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { flow, set, omit } from 'lodash/fp'; +import { flow, omit } from 'lodash/fp'; +import set from 'set-value'; import { SearchResponse } from 'elasticsearch'; import { Logger } from '../../../../../../../src/core/server'; @@ -55,8 +56,11 @@ export const transformAnomalyFieldsToEcs = (anomaly: Anomaly): EcsAnomaly => { } const omitDottedFields = omit(errantFields.map(field => field.name)); - const setNestedFields = errantFields.map(field => set(field.name, field.value)); - const setTimestamp = set('@timestamp', new Date(timestamp).toISOString()); + const setNestedFields = errantFields.map(field => (_anomaly: Anomaly) => + set(_anomaly, field.name, field.value) + ); + const setTimestamp = (_anomaly: Anomaly) => + set(_anomaly, '@timestamp', new Date(timestamp).toISOString()); return flow(omitDottedFields, setNestedFields, setTimestamp)(anomaly); }; diff --git a/yarn.lock b/yarn.lock index ee00ef283f07c0..94e6a0a11aa993 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4798,6 +4798,11 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" integrity sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ== +"@types/set-value@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/set-value/-/set-value-2.0.0.tgz#63d386b103926dcf49b50e16e0f6dd49983046be" + integrity sha512-k8dCJEC80F/mbsIOZ5Hj3YSzTVVVBwMdtP/M9Rtc2TM4F5etVd+2UG8QUiAUfbXm4fABedL2tBZnrBheY7UwpA== + "@types/shot@*": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/shot/-/shot-4.0.0.tgz#7545500c489b65c69b5bc5446ba4fef3bd26af92" @@ -26910,6 +26915,13 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" +set-value@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-3.0.2.tgz#74e8ecd023c33d0f77199d415409a40f21e61b90" + integrity sha512-npjkVoz+ank0zjlV9F47Fdbjfj/PfXyVhZvGALWsyIYU/qrMzpi6avjKW3/7KeSU2Df3I46BrN1xOI1+6vW0hA== + dependencies: + is-plain-object "^2.0.4" + setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" From bac638a37e5dc670cd1c6c535e1f9fcd77ef8f64 Mon Sep 17 00:00:00 2001 From: Dmitry Lemeshko Date: Wed, 29 Apr 2020 20:00:14 +0300 Subject: [PATCH 20/26] Update jest config for coverage (#64648) * set files to track for coverage collection * increase timeout to 4h * trying to add detectOpenHandles to avoid worker stuck * update config * make config paths more common * update configs * update jest oss config * exclude 'tests' folder for coverage --- .ci/Jenkinsfile_coverage | 2 +- src/dev/jest/config.js | 1 + test/scripts/jenkins_xpack.sh | 2 +- x-pack/dev-tools/jest/create_jest_config.js | 14 ++++++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.ci/Jenkinsfile_coverage b/.ci/Jenkinsfile_coverage index f2a58e7b6a7ac5..c474998e6fd3db 100644 --- a/.ci/Jenkinsfile_coverage +++ b/.ci/Jenkinsfile_coverage @@ -3,7 +3,7 @@ library 'kibana-pipeline-library' kibanaLibrary.load() // load from the Jenkins instance -kibanaPipeline(timeoutMinutes: 180) { +kibanaPipeline(timeoutMinutes: 240) { catchErrors { withEnv([ 'CODE_COVERAGE=1', // Needed for multiple ci scripts, such as remote.ts, test/scripts/*.sh, schema.js, etc. diff --git a/src/dev/jest/config.js b/src/dev/jest/config.js index 43a2cbd78c5023..c5387590fcf661 100644 --- a/src/dev/jest/config.js +++ b/src/dev/jest/config.js @@ -40,6 +40,7 @@ export default { ], collectCoverageFrom: [ 'src/plugins/**/*.{ts,tsx}', + '!src/plugins/**/{__test__,__snapshots__,__examples__,mocks,tests}/**/*', '!src/plugins/**/*.d.ts', 'packages/kbn-ui-framework/src/components/**/*.js', '!packages/kbn-ui-framework/src/components/index.js', diff --git a/test/scripts/jenkins_xpack.sh b/test/scripts/jenkins_xpack.sh index 67d88b308ed91c..951ba8e22d8858 100755 --- a/test/scripts/jenkins_xpack.sh +++ b/test/scripts/jenkins_xpack.sh @@ -39,7 +39,7 @@ else # build runtime for canvas echo "NODE_ENV=$NODE_ENV" node ./legacy/plugins/canvas/scripts/shareable_runtime - node --max-old-space-size=6144 scripts/jest --ci --verbose --coverage + node --max-old-space-size=6144 scripts/jest --ci --verbose --detectOpenHandles --coverage # rename file in order to be unique one test -f ../target/kibana-coverage/jest/coverage-final.json \ && mv ../target/kibana-coverage/jest/coverage-final.json \ diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js index af5ace8e3cd3b7..4f1251321b0054 100644 --- a/x-pack/dev-tools/jest/create_jest_config.js +++ b/x-pack/dev-tools/jest/create_jest_config.js @@ -34,6 +34,20 @@ export function createJestConfig({ kibanaDirectory, xPackKibanaDirectory }) { '^test_utils/stub_web_worker': `${xPackKibanaDirectory}/test_utils/stub_web_worker.ts`, '^(!!)?file-loader!': fileMockPath, }, + collectCoverageFrom: [ + 'legacy/plugins/**/*.{js,jsx,ts,tsx}', + 'legacy/server/**/*.{js,jsx,ts,tsx}', + 'plugins/**/*.{js,jsx,ts,tsx}', + '!**/{__test__,__snapshots__,__examples__,integration_tests,tests}/**', + '!**/*.test.{js,ts,tsx}', + '!**/flot-charts/**', + '!**/test/**', + '!**/build/**', + '!**/scripts/**', + '!**/mocks/**', + '!**/plugins/apm/e2e/**', + ], + coveragePathIgnorePatterns: ['.*\\.d\\.ts'], coverageDirectory: '/../target/kibana-coverage/jest', coverageReporters: !!process.env.CODE_COVERAGE ? ['json'] : ['html'], setupFiles: [ From d8c15f5ad38c0ed480fc90cf7c8381aad04f0609 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 29 Apr 2020 18:25:48 +0100 Subject: [PATCH 21/26] [ML] Adding endpoint capability checks (#64662) * [ML] Adding endpoint capability checks * adding missing capability checks * fixing test * removing commented code * fixing functional test * fixing functional tests * changes based on review Co-authored-by: Elastic Machine --- .../plugins/ml/common/types/capabilities.ts | 32 +++- .../capabilities/check_capabilities.test.ts | 159 ++++++++++++++---- .../lib/capabilities/check_capabilities.ts | 2 + x-pack/plugins/ml/server/plugin.ts | 14 +- .../plugins/ml/server/routes/annotations.ts | 9 + .../ml/server/routes/anomaly_detectors.ts | 45 +++++ x-pack/plugins/ml/server/routes/calendars.ts | 15 ++ .../ml/server/routes/data_frame_analytics.ts | 33 ++++ .../ml/server/routes/data_visualizer.ts | 6 + x-pack/plugins/ml/server/routes/datafeeds.ts | 30 ++++ .../ml/server/routes/fields_service.ts | 7 +- .../ml/server/routes/file_data_visualizer.ts | 2 + x-pack/plugins/ml/server/routes/filters.ts | 18 ++ x-pack/plugins/ml/server/routes/indices.ts | 3 + .../ml/server/routes/job_audit_messages.ts | 6 + .../plugins/ml/server/routes/job_service.ts | 80 ++++++--- .../ml/server/routes/job_validation.ts | 12 ++ x-pack/plugins/ml/server/routes/modules.ts | 12 ++ .../ml/server/routes/notification_settings.ts | 3 + .../ml/server/routes/results_service.ts | 15 ++ x-pack/plugins/ml/server/routes/system.ts | 16 ++ x-pack/plugins/ml/server/types.ts | 4 - .../apis/ml/anomaly_detectors/create.ts | 9 +- .../apis/ml/jobs/jobs_summary.ts | 4 +- .../apis/ml/modules/setup_module.ts | 7 +- 25 files changed, 456 insertions(+), 87 deletions(-) diff --git a/x-pack/plugins/ml/common/types/capabilities.ts b/x-pack/plugins/ml/common/types/capabilities.ts index 2a449c95faa5b5..da5fd3ac252096 100644 --- a/x-pack/plugins/ml/common/types/capabilities.ts +++ b/x-pack/plugins/ml/common/types/capabilities.ts @@ -7,6 +7,7 @@ import { KibanaRequest } from 'kibana/server'; export const userMlCapabilities = { + canAccessML: false, // Anomaly Detection canGetJobs: false, canGetDatafeeds: false, @@ -18,6 +19,10 @@ export const userMlCapabilities = { canGetFilters: false, // Data Frame Analytics canGetDataFrameAnalytics: false, + // Annotations + canGetAnnotations: false, + canCreateAnnotation: false, + canDeleteAnnotation: false, }; export const adminMlCapabilities = { @@ -26,9 +31,11 @@ export const adminMlCapabilities = { canDeleteJob: false, canOpenJob: false, canCloseJob: false, + canUpdateJob: false, canForecastJob: false, + canCreateDatafeed: false, + canDeleteDatafeed: false, canStartStopDatafeed: false, - canUpdateJob: false, canUpdateDatafeed: false, canPreviewDatafeed: false, // Calendars @@ -38,8 +45,8 @@ export const adminMlCapabilities = { canCreateFilter: false, canDeleteFilter: false, // Data Frame Analytics - canDeleteDataFrameAnalytics: false, canCreateDataFrameAnalytics: false, + canDeleteDataFrameAnalytics: false, canStartStopDataFrameAnalytics: false, }; @@ -47,7 +54,9 @@ export type UserMlCapabilities = typeof userMlCapabilities; export type AdminMlCapabilities = typeof adminMlCapabilities; export type MlCapabilities = UserMlCapabilities & AdminMlCapabilities; -export const basicLicenseMlCapabilities = ['canFindFileStructure'] as Array; +export const basicLicenseMlCapabilities = ['canAccessML', 'canFindFileStructure'] as Array< + keyof MlCapabilities +>; export function getDefaultCapabilities(): MlCapabilities { return { @@ -56,6 +65,23 @@ export function getDefaultCapabilities(): MlCapabilities { }; } +export function getPluginPrivileges() { + const userMlCapabilitiesKeys = Object.keys(userMlCapabilities); + const adminMlCapabilitiesKeys = Object.keys(adminMlCapabilities); + const allMlCapabilities = [...adminMlCapabilitiesKeys, ...userMlCapabilitiesKeys]; + + return { + user: { + ui: userMlCapabilitiesKeys, + api: userMlCapabilitiesKeys.map(k => `ml:${k}`), + }, + admin: { + ui: allMlCapabilities, + api: allMlCapabilities.map(k => `ml:${k}`), + }, + }; +} + export interface MlCapabilitiesResponse { capabilities: MlCapabilities; upgradeInProgress: boolean; diff --git a/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts b/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts index 5093801d2d1846..b6e95ae8373ee1 100644 --- a/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts +++ b/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.test.ts @@ -36,7 +36,7 @@ describe('check_capabilities', () => { ); const { capabilities } = await getCapabilities(); const count = Object.keys(capabilities).length; - expect(count).toBe(22); + expect(count).toBe(28); done(); }); }); @@ -49,28 +49,42 @@ describe('check_capabilities', () => { mlLicense, mlIsEnabled ); - const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities(); + const { + capabilities, + upgradeInProgress, + mlFeatureEnabledInSpace, + isPlatinumOrTrialLicense, + } = await getCapabilities(); expect(upgradeInProgress).toBe(false); expect(mlFeatureEnabledInSpace).toBe(true); + expect(isPlatinumOrTrialLicense).toBe(true); + + expect(capabilities.canAccessML).toBe(true); expect(capabilities.canGetJobs).toBe(true); + expect(capabilities.canGetDatafeeds).toBe(true); + expect(capabilities.canGetCalendars).toBe(true); + expect(capabilities.canFindFileStructure).toBe(true); + expect(capabilities.canGetFilters).toBe(true); + expect(capabilities.canGetDataFrameAnalytics).toBe(true); + expect(capabilities.canGetAnnotations).toBe(true); + expect(capabilities.canCreateAnnotation).toBe(true); + expect(capabilities.canDeleteAnnotation).toBe(true); + expect(capabilities.canCreateJob).toBe(false); expect(capabilities.canDeleteJob).toBe(false); expect(capabilities.canOpenJob).toBe(false); expect(capabilities.canCloseJob).toBe(false); expect(capabilities.canForecastJob).toBe(false); - expect(capabilities.canGetDatafeeds).toBe(true); expect(capabilities.canStartStopDatafeed).toBe(false); expect(capabilities.canUpdateJob).toBe(false); + expect(capabilities.canCreateDatafeed).toBe(false); + expect(capabilities.canDeleteDatafeed).toBe(false); expect(capabilities.canUpdateDatafeed).toBe(false); expect(capabilities.canPreviewDatafeed).toBe(false); - expect(capabilities.canGetCalendars).toBe(true); expect(capabilities.canCreateCalendar).toBe(false); expect(capabilities.canDeleteCalendar).toBe(false); - expect(capabilities.canGetFilters).toBe(true); expect(capabilities.canCreateFilter).toBe(false); expect(capabilities.canDeleteFilter).toBe(false); - expect(capabilities.canFindFileStructure).toBe(true); - expect(capabilities.canGetDataFrameAnalytics).toBe(true); expect(capabilities.canDeleteDataFrameAnalytics).toBe(false); expect(capabilities.canCreateDataFrameAnalytics).toBe(false); expect(capabilities.canStartStopDataFrameAnalytics).toBe(false); @@ -84,28 +98,42 @@ describe('check_capabilities', () => { mlLicense, mlIsEnabled ); - const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities(); + const { + capabilities, + upgradeInProgress, + mlFeatureEnabledInSpace, + isPlatinumOrTrialLicense, + } = await getCapabilities(); expect(upgradeInProgress).toBe(false); expect(mlFeatureEnabledInSpace).toBe(true); + expect(isPlatinumOrTrialLicense).toBe(true); + + expect(capabilities.canAccessML).toBe(true); expect(capabilities.canGetJobs).toBe(true); + expect(capabilities.canGetDatafeeds).toBe(true); + expect(capabilities.canGetCalendars).toBe(true); + expect(capabilities.canFindFileStructure).toBe(true); + expect(capabilities.canGetFilters).toBe(true); + expect(capabilities.canGetDataFrameAnalytics).toBe(true); + expect(capabilities.canGetAnnotations).toBe(true); + expect(capabilities.canCreateAnnotation).toBe(true); + expect(capabilities.canDeleteAnnotation).toBe(true); + expect(capabilities.canCreateJob).toBe(true); expect(capabilities.canDeleteJob).toBe(true); expect(capabilities.canOpenJob).toBe(true); expect(capabilities.canCloseJob).toBe(true); expect(capabilities.canForecastJob).toBe(true); - expect(capabilities.canGetDatafeeds).toBe(true); expect(capabilities.canStartStopDatafeed).toBe(true); expect(capabilities.canUpdateJob).toBe(true); + expect(capabilities.canCreateDatafeed).toBe(true); + expect(capabilities.canDeleteDatafeed).toBe(true); expect(capabilities.canUpdateDatafeed).toBe(true); expect(capabilities.canPreviewDatafeed).toBe(true); - expect(capabilities.canGetCalendars).toBe(true); expect(capabilities.canCreateCalendar).toBe(true); expect(capabilities.canDeleteCalendar).toBe(true); - expect(capabilities.canGetFilters).toBe(true); expect(capabilities.canCreateFilter).toBe(true); expect(capabilities.canDeleteFilter).toBe(true); - expect(capabilities.canFindFileStructure).toBe(true); - expect(capabilities.canGetDataFrameAnalytics).toBe(true); expect(capabilities.canDeleteDataFrameAnalytics).toBe(true); expect(capabilities.canCreateDataFrameAnalytics).toBe(true); expect(capabilities.canStartStopDataFrameAnalytics).toBe(true); @@ -119,28 +147,42 @@ describe('check_capabilities', () => { mlLicense, mlIsEnabled ); - const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities(); + const { + capabilities, + upgradeInProgress, + mlFeatureEnabledInSpace, + isPlatinumOrTrialLicense, + } = await getCapabilities(); expect(upgradeInProgress).toBe(true); expect(mlFeatureEnabledInSpace).toBe(true); + expect(isPlatinumOrTrialLicense).toBe(true); + + expect(capabilities.canAccessML).toBe(true); expect(capabilities.canGetJobs).toBe(true); + expect(capabilities.canGetDatafeeds).toBe(true); + expect(capabilities.canGetCalendars).toBe(true); + expect(capabilities.canFindFileStructure).toBe(true); + expect(capabilities.canGetFilters).toBe(true); + expect(capabilities.canGetDataFrameAnalytics).toBe(true); + expect(capabilities.canGetAnnotations).toBe(true); + expect(capabilities.canCreateAnnotation).toBe(false); + expect(capabilities.canDeleteAnnotation).toBe(false); + expect(capabilities.canCreateJob).toBe(false); expect(capabilities.canDeleteJob).toBe(false); expect(capabilities.canOpenJob).toBe(false); expect(capabilities.canCloseJob).toBe(false); expect(capabilities.canForecastJob).toBe(false); - expect(capabilities.canGetDatafeeds).toBe(true); expect(capabilities.canStartStopDatafeed).toBe(false); expect(capabilities.canUpdateJob).toBe(false); + expect(capabilities.canCreateDatafeed).toBe(false); + expect(capabilities.canDeleteDatafeed).toBe(false); expect(capabilities.canUpdateDatafeed).toBe(false); expect(capabilities.canPreviewDatafeed).toBe(false); - expect(capabilities.canGetCalendars).toBe(true); expect(capabilities.canCreateCalendar).toBe(false); expect(capabilities.canDeleteCalendar).toBe(false); - expect(capabilities.canGetFilters).toBe(true); expect(capabilities.canCreateFilter).toBe(false); expect(capabilities.canDeleteFilter).toBe(false); - expect(capabilities.canFindFileStructure).toBe(true); - expect(capabilities.canGetDataFrameAnalytics).toBe(true); expect(capabilities.canDeleteDataFrameAnalytics).toBe(false); expect(capabilities.canCreateDataFrameAnalytics).toBe(false); expect(capabilities.canStartStopDataFrameAnalytics).toBe(false); @@ -154,28 +196,42 @@ describe('check_capabilities', () => { mlLicense, mlIsEnabled ); - const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities(); + const { + capabilities, + upgradeInProgress, + mlFeatureEnabledInSpace, + isPlatinumOrTrialLicense, + } = await getCapabilities(); expect(upgradeInProgress).toBe(true); expect(mlFeatureEnabledInSpace).toBe(true); + expect(isPlatinumOrTrialLicense).toBe(true); + + expect(capabilities.canAccessML).toBe(true); expect(capabilities.canGetJobs).toBe(true); + expect(capabilities.canGetDatafeeds).toBe(true); + expect(capabilities.canGetCalendars).toBe(true); + expect(capabilities.canFindFileStructure).toBe(true); + expect(capabilities.canGetFilters).toBe(true); + expect(capabilities.canGetDataFrameAnalytics).toBe(true); + expect(capabilities.canGetAnnotations).toBe(true); + expect(capabilities.canCreateAnnotation).toBe(false); + expect(capabilities.canDeleteAnnotation).toBe(false); + expect(capabilities.canCreateJob).toBe(false); expect(capabilities.canDeleteJob).toBe(false); expect(capabilities.canOpenJob).toBe(false); expect(capabilities.canCloseJob).toBe(false); expect(capabilities.canForecastJob).toBe(false); - expect(capabilities.canGetDatafeeds).toBe(true); expect(capabilities.canStartStopDatafeed).toBe(false); expect(capabilities.canUpdateJob).toBe(false); + expect(capabilities.canCreateDatafeed).toBe(false); + expect(capabilities.canDeleteDatafeed).toBe(false); expect(capabilities.canUpdateDatafeed).toBe(false); expect(capabilities.canPreviewDatafeed).toBe(false); - expect(capabilities.canGetCalendars).toBe(true); expect(capabilities.canCreateCalendar).toBe(false); expect(capabilities.canDeleteCalendar).toBe(false); - expect(capabilities.canGetFilters).toBe(true); expect(capabilities.canCreateFilter).toBe(false); expect(capabilities.canDeleteFilter).toBe(false); - expect(capabilities.canFindFileStructure).toBe(true); - expect(capabilities.canGetDataFrameAnalytics).toBe(true); expect(capabilities.canDeleteDataFrameAnalytics).toBe(false); expect(capabilities.canCreateDataFrameAnalytics).toBe(false); expect(capabilities.canStartStopDataFrameAnalytics).toBe(false); @@ -189,28 +245,42 @@ describe('check_capabilities', () => { mlLicense, mlIsNotEnabled ); - const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities(); + const { + capabilities, + upgradeInProgress, + mlFeatureEnabledInSpace, + isPlatinumOrTrialLicense, + } = await getCapabilities(); expect(upgradeInProgress).toBe(false); expect(mlFeatureEnabledInSpace).toBe(false); + expect(isPlatinumOrTrialLicense).toBe(true); + + expect(capabilities.canAccessML).toBe(false); expect(capabilities.canGetJobs).toBe(false); + expect(capabilities.canGetDatafeeds).toBe(false); + expect(capabilities.canGetCalendars).toBe(false); + expect(capabilities.canFindFileStructure).toBe(false); + expect(capabilities.canGetFilters).toBe(false); + expect(capabilities.canGetDataFrameAnalytics).toBe(false); + expect(capabilities.canGetAnnotations).toBe(false); + expect(capabilities.canCreateAnnotation).toBe(false); + expect(capabilities.canDeleteAnnotation).toBe(false); + expect(capabilities.canCreateJob).toBe(false); expect(capabilities.canDeleteJob).toBe(false); expect(capabilities.canOpenJob).toBe(false); expect(capabilities.canCloseJob).toBe(false); expect(capabilities.canForecastJob).toBe(false); - expect(capabilities.canGetDatafeeds).toBe(false); expect(capabilities.canStartStopDatafeed).toBe(false); expect(capabilities.canUpdateJob).toBe(false); + expect(capabilities.canCreateDatafeed).toBe(false); + expect(capabilities.canDeleteDatafeed).toBe(false); expect(capabilities.canUpdateDatafeed).toBe(false); expect(capabilities.canPreviewDatafeed).toBe(false); - expect(capabilities.canGetCalendars).toBe(false); expect(capabilities.canCreateCalendar).toBe(false); expect(capabilities.canDeleteCalendar).toBe(false); - expect(capabilities.canGetFilters).toBe(false); expect(capabilities.canCreateFilter).toBe(false); expect(capabilities.canDeleteFilter).toBe(false); - expect(capabilities.canFindFileStructure).toBe(false); - expect(capabilities.canGetDataFrameAnalytics).toBe(false); expect(capabilities.canDeleteDataFrameAnalytics).toBe(false); expect(capabilities.canCreateDataFrameAnalytics).toBe(false); expect(capabilities.canStartStopDataFrameAnalytics).toBe(false); @@ -225,28 +295,43 @@ describe('check_capabilities', () => { mlLicenseBasic, mlIsNotEnabled ); - const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getCapabilities(); + const { + capabilities, + upgradeInProgress, + mlFeatureEnabledInSpace, + isPlatinumOrTrialLicense, + } = await getCapabilities(); + expect(upgradeInProgress).toBe(false); expect(mlFeatureEnabledInSpace).toBe(false); + expect(isPlatinumOrTrialLicense).toBe(false); + + expect(capabilities.canAccessML).toBe(false); expect(capabilities.canGetJobs).toBe(false); + expect(capabilities.canGetDatafeeds).toBe(false); + expect(capabilities.canGetCalendars).toBe(false); + expect(capabilities.canFindFileStructure).toBe(false); + expect(capabilities.canGetFilters).toBe(false); + expect(capabilities.canGetDataFrameAnalytics).toBe(false); + expect(capabilities.canGetAnnotations).toBe(false); + expect(capabilities.canCreateAnnotation).toBe(false); + expect(capabilities.canDeleteAnnotation).toBe(false); + expect(capabilities.canCreateJob).toBe(false); expect(capabilities.canDeleteJob).toBe(false); expect(capabilities.canOpenJob).toBe(false); expect(capabilities.canCloseJob).toBe(false); expect(capabilities.canForecastJob).toBe(false); - expect(capabilities.canGetDatafeeds).toBe(false); expect(capabilities.canStartStopDatafeed).toBe(false); expect(capabilities.canUpdateJob).toBe(false); + expect(capabilities.canCreateDatafeed).toBe(false); + expect(capabilities.canDeleteDatafeed).toBe(false); expect(capabilities.canUpdateDatafeed).toBe(false); expect(capabilities.canPreviewDatafeed).toBe(false); - expect(capabilities.canGetCalendars).toBe(false); expect(capabilities.canCreateCalendar).toBe(false); expect(capabilities.canDeleteCalendar).toBe(false); - expect(capabilities.canGetFilters).toBe(false); expect(capabilities.canCreateFilter).toBe(false); expect(capabilities.canDeleteFilter).toBe(false); - expect(capabilities.canFindFileStructure).toBe(false); - expect(capabilities.canGetDataFrameAnalytics).toBe(false); expect(capabilities.canDeleteDataFrameAnalytics).toBe(false); expect(capabilities.canCreateDataFrameAnalytics).toBe(false); expect(capabilities.canStartStopDataFrameAnalytics).toBe(false); diff --git a/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.ts b/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.ts index a2ad83c5522de3..d955cf981faca6 100644 --- a/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.ts +++ b/x-pack/plugins/ml/server/lib/capabilities/check_capabilities.ts @@ -44,4 +44,6 @@ function disableAdminPrivileges(capabilities: MlCapabilities) { Object.keys(adminMlCapabilities).forEach(k => { capabilities[k as keyof MlCapabilities] = false; }); + capabilities.canCreateAnnotation = false; + capabilities.canDeleteAnnotation = false; } diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index 64f8eb4b0acd3a..969b74194148b3 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -45,7 +45,7 @@ import { systemRoutes } from './routes/system'; import { MlLicense } from '../common/license'; import { MlServerLicense } from './lib/license'; import { createSharedServices, SharedServices } from './shared_services'; -import { userMlCapabilities, adminMlCapabilities } from '../common/types/capabilities'; +import { getPluginPrivileges } from '../common/types/capabilities'; import { setupCapabilitiesSwitcher } from './lib/capabilities'; import { registerKibanaSettings } from './lib/register_settings'; @@ -75,8 +75,7 @@ export class MlServerPlugin implements Plugin { try { @@ -86,6 +89,9 @@ export function annotationRoutes( validate: { body: indexAnnotationSchema, }, + options: { + tags: ['access:ml:canCreateAnnotation'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -130,6 +136,9 @@ export function annotationRoutes( validate: { params: deleteAnnotationSchema, }, + options: { + tags: ['access:ml:canDeleteAnnotation'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/anomaly_detectors.ts b/x-pack/plugins/ml/server/routes/anomaly_detectors.ts index ca63d69f403f6b..63cd5498231af5 100644 --- a/x-pack/plugins/ml/server/routes/anomaly_detectors.ts +++ b/x-pack/plugins/ml/server/routes/anomaly_detectors.ts @@ -37,6 +37,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { { path: '/api/ml/anomaly_detectors', validate: false, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -65,6 +68,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: jobIdSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -93,6 +99,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { { path: '/api/ml/anomaly_detectors/_stats', validate: false, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -121,6 +130,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: jobIdSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -154,6 +166,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { params: jobIdSchema, body: schema.object(anomalyDetectionJobSchema), }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -188,6 +203,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { params: jobIdSchema, body: anomalyDetectionUpdateJobSchema, }, + options: { + tags: ['access:ml:canUpdateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -220,6 +238,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: jobIdSchema, }, + options: { + tags: ['access:ml:canOpenJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -251,6 +272,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: jobIdSchema, }, + options: { + tags: ['access:ml:canCloseJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -286,6 +310,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: jobIdSchema, }, + options: { + tags: ['access:ml:canDeleteJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -319,6 +346,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { validate: { body: schema.any(), }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -351,6 +381,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { params: jobIdSchema, body: forecastAnomalyDetector, }, + options: { + tags: ['access:ml:canForecastJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -389,6 +422,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { params: jobIdSchema, body: getRecordsSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -425,6 +461,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { params: getBucketParamsSchema, body: getBucketsSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -462,6 +501,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { params: jobIdSchema, body: getOverallBucketsSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -496,6 +538,9 @@ export function jobRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: getCategoriesSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/calendars.ts b/x-pack/plugins/ml/server/routes/calendars.ts index a17601f74ae93e..9c80651a13999e 100644 --- a/x-pack/plugins/ml/server/routes/calendars.ts +++ b/x-pack/plugins/ml/server/routes/calendars.ts @@ -52,6 +52,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) { { path: '/api/ml/calendars', validate: false, + options: { + tags: ['access:ml:canGetCalendars'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -81,6 +84,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) { validate: { params: calendarIdsSchema, }, + options: { + tags: ['access:ml:canGetCalendars'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { let returnValue; @@ -117,6 +123,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) { validate: { body: calendarSchema, }, + options: { + tags: ['access:ml:canCreateCalendar'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -149,6 +158,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) { params: calendarIdSchema, body: calendarSchema, }, + options: { + tags: ['access:ml:canCreateCalendar'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -180,6 +192,9 @@ export function calendars({ router, mlLicense }: RouteInitialization) { validate: { params: calendarIdSchema, }, + options: { + tags: ['access:ml:canDeleteCalendar'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index dd9e0ea66aa9dd..32cb2b343f8760 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -33,6 +33,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat { path: '/api/ml/data_frame/analytics', validate: false, + options: { + tags: ['access:ml:canGetDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -61,6 +64,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat validate: { params: analyticsIdSchema, }, + options: { + tags: ['access:ml:canGetDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -88,6 +94,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat { path: '/api/ml/data_frame/analytics/_stats', validate: false, + options: { + tags: ['access:ml:canGetDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -118,6 +127,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat validate: { params: analyticsIdSchema, }, + options: { + tags: ['access:ml:canGetDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -155,6 +167,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat params: analyticsIdSchema, body: dataAnalyticsJobConfigSchema, }, + options: { + tags: ['access:ml:canCreateDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -190,6 +205,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat validate: { body: dataAnalyticsEvaluateSchema, }, + options: { + tags: ['access:ml:canCreateDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -224,6 +242,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat validate: { body: dataAnalyticsExplainSchema, }, + options: { + tags: ['access:ml:canCreateDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -257,6 +278,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat validate: { params: analyticsIdSchema, }, + options: { + tags: ['access:ml:canDeleteDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -291,6 +315,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat validate: { params: analyticsIdSchema, }, + options: { + tags: ['access:ml:canStartStopDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -324,6 +351,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat params: analyticsIdSchema, query: stopsDataFrameAnalyticsJobQuerySchema, }, + options: { + tags: ['access:ml:canStartStopDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -364,6 +394,9 @@ export function dataFrameAnalyticsRoutes({ router, mlLicense }: RouteInitializat validate: { params: analyticsIdSchema, }, + options: { + tags: ['access:ml:canGetDataFrameAnalytics'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/data_visualizer.ts b/x-pack/plugins/ml/server/routes/data_visualizer.ts index 20029fbd8d1a6b..04008a896a1a22 100644 --- a/x-pack/plugins/ml/server/routes/data_visualizer.ts +++ b/x-pack/plugins/ml/server/routes/data_visualizer.ts @@ -88,6 +88,9 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) params: indexPatternTitleSchema, body: dataVisualizerFieldStatsSchema, }, + options: { + tags: ['access:ml:canAccessML'], + }, }, mlLicense.basicLicenseAPIGuard(async (context, request, response) => { try { @@ -150,6 +153,9 @@ export function dataVisualizerRoutes({ router, mlLicense }: RouteInitialization) params: indexPatternTitleSchema, body: dataVisualizerOverallStatsSchema, }, + options: { + tags: ['access:ml:canAccessML'], + }, }, mlLicense.basicLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/datafeeds.ts b/x-pack/plugins/ml/server/routes/datafeeds.ts index ec667e1d305f52..1fa1d408372da3 100644 --- a/x-pack/plugins/ml/server/routes/datafeeds.ts +++ b/x-pack/plugins/ml/server/routes/datafeeds.ts @@ -28,6 +28,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { { path: '/api/ml/datafeeds', validate: false, + options: { + tags: ['access:ml:canGetDatafeeds'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -57,6 +60,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: datafeedIdSchema, }, + options: { + tags: ['access:ml:canGetDatafeeds'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -83,6 +89,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { { path: '/api/ml/datafeeds/_stats', validate: false, + options: { + tags: ['access:ml:canGetDatafeeds'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -112,6 +121,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: datafeedIdSchema, }, + options: { + tags: ['access:ml:canGetDatafeeds'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -146,6 +158,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { params: datafeedIdSchema, body: datafeedConfigSchema, }, + options: { + tags: ['access:ml:canCreateDatafeed'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -181,6 +196,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { params: datafeedIdSchema, body: datafeedConfigSchema, }, + options: { + tags: ['access:ml:canUpdateDatafeed'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -216,6 +234,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { params: datafeedIdSchema, query: deleteDatafeedQuerySchema, }, + options: { + tags: ['access:ml:canDeleteDatafeed'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -255,6 +276,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { params: datafeedIdSchema, body: startDatafeedSchema, }, + options: { + tags: ['access:ml:canStartStopDatafeed'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -291,6 +315,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: datafeedIdSchema, }, + options: { + tags: ['access:ml:canStartStopDatafeed'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -324,6 +351,9 @@ export function dataFeedRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: datafeedIdSchema, }, + options: { + tags: ['access:ml:canPreviewDatafeed'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/fields_service.ts b/x-pack/plugins/ml/server/routes/fields_service.ts index 577e8e0161342a..b0f13df294145e 100644 --- a/x-pack/plugins/ml/server/routes/fields_service.ts +++ b/x-pack/plugins/ml/server/routes/fields_service.ts @@ -46,8 +46,10 @@ export function fieldsService({ router, mlLicense }: RouteInitialization) { validate: { body: getCardinalityOfFieldsSchema, }, + options: { + tags: ['access:ml:canAccessML'], + }, }, - mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { const resp = await getCardinalityOfFields(context, request.body); @@ -79,6 +81,9 @@ export function fieldsService({ router, mlLicense }: RouteInitialization) { validate: { body: getTimeFieldRangeSchema, }, + options: { + tags: ['access:ml:canAccessML'], + }, }, mlLicense.basicLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/file_data_visualizer.ts b/x-pack/plugins/ml/server/routes/file_data_visualizer.ts index 3f3fc3f547b6a0..0f389f9505943b 100644 --- a/x-pack/plugins/ml/server/routes/file_data_visualizer.ts +++ b/x-pack/plugins/ml/server/routes/file_data_visualizer.ts @@ -71,6 +71,7 @@ export function fileDataVisualizerRoutes({ router, mlLicense }: RouteInitializat accepts: ['text/*', 'application/json'], maxBytes: MAX_FILE_SIZE_BYTES, }, + tags: ['access:ml:canFindFileStructure'], }, }, mlLicense.basicLicenseAPIGuard(async (context, request, response) => { @@ -105,6 +106,7 @@ export function fileDataVisualizerRoutes({ router, mlLicense }: RouteInitializat accepts: ['application/json'], maxBytes: MAX_FILE_SIZE_BYTES, }, + tags: ['access:ml:canFindFileStructure'], }, }, mlLicense.basicLicenseAPIGuard(async (context, request, response) => { diff --git a/x-pack/plugins/ml/server/routes/filters.ts b/x-pack/plugins/ml/server/routes/filters.ts index 738c25070358d1..d5287c349a8fca 100644 --- a/x-pack/plugins/ml/server/routes/filters.ts +++ b/x-pack/plugins/ml/server/routes/filters.ts @@ -57,6 +57,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { { path: '/api/ml/filters', validate: false, + options: { + tags: ['access:ml:canGetFilters'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -89,6 +92,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: filterIdSchema, }, + options: { + tags: ['access:ml:canGetFilters'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -120,6 +126,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { validate: { body: createFilterSchema, }, + options: { + tags: ['access:ml:canCreateFilter'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -155,6 +164,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { params: filterIdSchema, body: updateFilterSchema, }, + options: { + tags: ['access:ml:canCreateFilter'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -186,6 +198,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { validate: { params: filterIdSchema, }, + options: { + tags: ['access:ml:canDeleteFilter'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -216,6 +231,9 @@ export function filtersRoutes({ router, mlLicense }: RouteInitialization) { { path: '/api/ml/filters/_stats', validate: false, + options: { + tags: ['access:ml:canGetFilters'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/indices.ts b/x-pack/plugins/ml/server/routes/indices.ts index e434936beba630..fb3ef7fc41c767 100644 --- a/x-pack/plugins/ml/server/routes/indices.ts +++ b/x-pack/plugins/ml/server/routes/indices.ts @@ -27,6 +27,9 @@ export function indicesRoutes({ router, mlLicense }: RouteInitialization) { validate: { body: indicesSchema, }, + options: { + tags: ['access:ml:canAccessML'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/job_audit_messages.ts b/x-pack/plugins/ml/server/routes/job_audit_messages.ts index 1fe5a7af95d4f0..5acc89e7d13be7 100644 --- a/x-pack/plugins/ml/server/routes/job_audit_messages.ts +++ b/x-pack/plugins/ml/server/routes/job_audit_messages.ts @@ -33,6 +33,9 @@ export function jobAuditMessagesRoutes({ router, mlLicense }: RouteInitializatio params: jobAuditMessagesJobIdSchema, query: jobAuditMessagesQuerySchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -67,6 +70,9 @@ export function jobAuditMessagesRoutes({ router, mlLicense }: RouteInitializatio validate: { query: jobAuditMessagesQuerySchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/job_service.ts b/x-pack/plugins/ml/server/routes/job_service.ts index 149ca2591fd765..05c44e1da97575 100644 --- a/x-pack/plugins/ml/server/routes/job_service.ts +++ b/x-pack/plugins/ml/server/routes/job_service.ts @@ -4,11 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; import { schema } from '@kbn/config-schema'; -import { KibanaRequest } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; -import { RouteInitialization, JobServiceRouteDeps } from '../types'; +import { RouteInitialization } from '../types'; import { categorizationFieldExamplesSchema, chartSchema, @@ -27,19 +25,7 @@ import { categorizationExamplesProvider } from '../models/job_service/new_job'; /** * Routes for job service */ -export function jobServiceRoutes( - { router, mlLicense }: RouteInitialization, - { resolveMlCapabilities }: JobServiceRouteDeps -) { - async function hasPermissionToCreateJobs(request: KibanaRequest) { - const mlCapabilities = await resolveMlCapabilities(request); - if (mlCapabilities === null) { - throw new Error('resolveMlCapabilities is not defined'); - } - - return mlCapabilities.canCreateJob; - } - +export function jobServiceRoutes({ router, mlLicense }: RouteInitialization) { /** * @apiGroup JobService * @@ -55,6 +41,9 @@ export function jobServiceRoutes( validate: { body: forceStartDatafeedSchema, }, + options: { + tags: ['access:ml:canStartStopDatafeed'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -86,6 +75,9 @@ export function jobServiceRoutes( validate: { body: datafeedIdsSchema, }, + options: { + tags: ['access:ml:canStartStopDatafeed'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -117,6 +109,9 @@ export function jobServiceRoutes( validate: { body: jobIdsSchema, }, + options: { + tags: ['access:ml:canDeleteJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -148,6 +143,9 @@ export function jobServiceRoutes( validate: { body: jobIdsSchema, }, + options: { + tags: ['access:ml:canCloseJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -184,6 +182,9 @@ export function jobServiceRoutes( validate: { body: jobIdsSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -215,6 +216,9 @@ export function jobServiceRoutes( validate: { body: schema.object(jobsWithTimerangeSchema), }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -245,6 +249,9 @@ export function jobServiceRoutes( validate: { body: jobIdsSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -272,6 +279,9 @@ export function jobServiceRoutes( { path: '/api/ml/jobs/groups', validate: false, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -302,6 +312,9 @@ export function jobServiceRoutes( validate: { body: schema.object(updateGroupsSchema), }, + options: { + tags: ['access:ml:canUpdateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -329,6 +342,9 @@ export function jobServiceRoutes( { path: '/api/ml/jobs/deleting_jobs_tasks', validate: false, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -359,6 +375,9 @@ export function jobServiceRoutes( validate: { body: jobIdsSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -389,6 +408,9 @@ export function jobServiceRoutes( params: schema.object({ indexPattern: schema.string() }), query: schema.maybe(schema.object({ rollup: schema.maybe(schema.string()) })), }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -422,6 +444,9 @@ export function jobServiceRoutes( validate: { body: schema.object(chartSchema), }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -474,6 +499,9 @@ export function jobServiceRoutes( validate: { body: schema.object(chartSchema), }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -522,6 +550,9 @@ export function jobServiceRoutes( { path: '/api/ml/jobs/all_jobs_and_group_ids', validate: false, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -552,6 +583,9 @@ export function jobServiceRoutes( validate: { body: schema.object(lookBackProgressSchema), }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -583,17 +617,12 @@ export function jobServiceRoutes( validate: { body: schema.object(categorizationFieldExamplesSchema), }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { - // due to the use of the _analyze endpoint which is called by the kibana user, - // basic job creation privileges are required to use this endpoint - if ((await hasPermissionToCreateJobs(request)) === false) { - throw Boom.forbidden( - 'Insufficient privileges, the machine_learning_admin role is required.' - ); - } - const { validateCategoryExamples } = categorizationExamplesProvider( context.ml!.mlClient.callAsCurrentUser, context.ml!.mlClient.callAsInternalUser @@ -644,6 +673,9 @@ export function jobServiceRoutes( validate: { body: schema.object(topCategoriesSchema), }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/job_validation.ts b/x-pack/plugins/ml/server/routes/job_validation.ts index dd2bd9deadf43f..632166d6d5fb8f 100644 --- a/x-pack/plugins/ml/server/routes/job_validation.ts +++ b/x-pack/plugins/ml/server/routes/job_validation.ts @@ -57,6 +57,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, validate: { body: estimateBucketSpanSchema, }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -106,6 +109,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, validate: { body: modelMemoryLimitSchema, }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -135,6 +141,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, validate: { body: validateCardinalitySchema, }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -167,6 +176,9 @@ export function jobValidationRoutes({ router, mlLicense }: RouteInitialization, validate: { body: validateJobSchema, }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/modules.ts b/x-pack/plugins/ml/server/routes/modules.ts index 2891144fc4574a..622ae66ede4264 100644 --- a/x-pack/plugins/ml/server/routes/modules.ts +++ b/x-pack/plugins/ml/server/routes/modules.ts @@ -97,6 +97,9 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { indexPatternTitle: schema.string(), }), }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -127,6 +130,9 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { ...getModuleIdParamSchema(true), }), }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -161,6 +167,9 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { params: schema.object(getModuleIdParamSchema()), body: setupModuleBodySchema, }, + options: { + tags: ['access:ml:canCreateJob'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -218,6 +227,9 @@ export function dataRecognizer({ router, mlLicense }: RouteInitialization) { validate: { params: schema.object(getModuleIdParamSchema()), }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/notification_settings.ts b/x-pack/plugins/ml/server/routes/notification_settings.ts index 59458b1e486db2..e4a9abb0784beb 100644 --- a/x-pack/plugins/ml/server/routes/notification_settings.ts +++ b/x-pack/plugins/ml/server/routes/notification_settings.ts @@ -22,6 +22,9 @@ export function notificationRoutes({ router, mlLicense }: RouteInitialization) { { path: '/api/ml/notification_settings', validate: false, + options: { + tags: ['access:ml:canAccessML'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/results_service.ts b/x-pack/plugins/ml/server/routes/results_service.ts index 89c267340fe52f..94ca0827ccfa59 100644 --- a/x-pack/plugins/ml/server/routes/results_service.ts +++ b/x-pack/plugins/ml/server/routes/results_service.ts @@ -88,6 +88,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) validate: { body: anomaliesTableDataSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -117,6 +120,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) validate: { body: categoryDefinitionSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -146,6 +152,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) validate: { body: maxAnomalyScoreSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -175,6 +184,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) validate: { body: categoryExamplesSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { @@ -204,6 +216,9 @@ export function resultsServiceRoutes({ router, mlLicense }: RouteInitialization) validate: { body: partitionFieldValuesSchema, }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/routes/system.ts b/x-pack/plugins/ml/server/routes/system.ts index d5fe45728c56c7..7ae7dd8eef0653 100644 --- a/x-pack/plugins/ml/server/routes/system.ts +++ b/x-pack/plugins/ml/server/routes/system.ts @@ -54,6 +54,9 @@ export function systemRoutes( validate: { body: schema.maybe(schema.any()), }, + options: { + tags: ['access:ml:canAccessML'], + }, }, mlLicense.basicLicenseAPIGuard(async (context, request, response) => { try { @@ -110,6 +113,9 @@ export function systemRoutes( { path: '/api/ml/ml_capabilities', validate: false, + options: { + tags: ['access:ml:canAccessML'], + }, }, mlLicense.basicLicenseAPIGuard(async (context, request, response) => { try { @@ -150,7 +156,11 @@ export function systemRoutes( { path: '/api/ml/ml_node_count', validate: false, + options: { + tags: ['access:ml:canGetJobs'], + }, }, + mlLicense.basicLicenseAPIGuard(async (context, request, response) => { try { // check for basic license first for consistency with other @@ -201,6 +211,9 @@ export function systemRoutes( { path: '/api/ml/info', validate: false, + options: { + tags: ['access:ml:canAccessML'], + }, }, mlLicense.basicLicenseAPIGuard(async (context, request, response) => { try { @@ -229,6 +242,9 @@ export function systemRoutes( validate: { body: schema.maybe(schema.any()), }, + options: { + tags: ['access:ml:canGetJobs'], + }, }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { diff --git a/x-pack/plugins/ml/server/types.ts b/x-pack/plugins/ml/server/types.ts index d4cd61a7fa4f71..678e81d3526ac8 100644 --- a/x-pack/plugins/ml/server/types.ts +++ b/x-pack/plugins/ml/server/types.ts @@ -30,10 +30,6 @@ export interface SystemRouteDeps { resolveMlCapabilities: ResolveMlCapabilities; } -export interface JobServiceRouteDeps { - resolveMlCapabilities: ResolveMlCapabilities; -} - export interface PluginsSetup { cloud: CloudSetup; features: FeaturesPluginSetup; diff --git a/x-pack/test/api_integration/apis/ml/anomaly_detectors/create.ts b/x-pack/test/api_integration/apis/ml/anomaly_detectors/create.ts index bbc766df34dcfe..10857caab98e27 100644 --- a/x-pack/test/api_integration/apis/ml/anomaly_detectors/create.ts +++ b/x-pack/test/api_integration/apis/ml/anomaly_detectors/create.ts @@ -91,12 +91,11 @@ export default ({ getService }: FtrProviderContext) => { model_plot_config: { enabled: true }, }, expected: { - responseCode: 403, + responseCode: 404, responseBody: { - statusCode: 403, - error: 'Forbidden', - message: - '[security_exception] action [cluster:admin/xpack/ml/job/put] is unauthorized for user [ml_viewer]', + statusCode: 404, + error: 'Not Found', + message: 'Not Found', }, }, }, diff --git a/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts b/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts index 6a57db1687868f..a5cb68d7821267 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts @@ -197,8 +197,8 @@ export default ({ getService }: FtrProviderContext) => { requestBody: {}, // Note that the jobs and datafeeds are loaded async so the actual error message is not deterministic. expected: { - responseCode: 403, - error: 'Forbidden', + responseCode: 404, + error: 'Not Found', }, }, ]; diff --git a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts index 23ddd3b63a2eff..c42fc95c1bc7f2 100644 --- a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts +++ b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts @@ -84,10 +84,9 @@ export default ({ getService }: FtrProviderContext) => { startDatafeed: false, }, expected: { - responseCode: 403, - error: 'Forbidden', - message: - '[security_exception] action [cluster:monitor/xpack/ml/info/get] is unauthorized for user [ml_unauthorized]', + responseCode: 404, + error: 'Not Found', + message: 'Not Found', }, }, ]; From 1512859e56d5196665ffbfaefd9b7a25d8b24100 Mon Sep 17 00:00:00 2001 From: "Christiane (Tina) Heiligers" Date: Wed, 29 Apr 2020 10:54:19 -0700 Subject: [PATCH 22/26] [Telemetry] oss api tests (#64602) * Adds telemetry API tests for oss * Modifies test expectations to match that within oss Co-authored-by: Elastic Machine --- test/api_integration/apis/index.js | 1 + test/api_integration/apis/telemetry/index.js | 26 ++++ test/api_integration/apis/telemetry/opt_in.ts | 123 ++++++++++++++++ .../apis/telemetry/telemetry_local.js | 133 ++++++++++++++++++ .../telemetry/telemetry_optin_notice_seen.ts | 59 ++++++++ 5 files changed, 342 insertions(+) create mode 100644 test/api_integration/apis/telemetry/index.js create mode 100644 test/api_integration/apis/telemetry/opt_in.ts create mode 100644 test/api_integration/apis/telemetry/telemetry_local.js create mode 100644 test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts diff --git a/test/api_integration/apis/index.js b/test/api_integration/apis/index.js index c5bfc847d0041f..0c4028905657d5 100644 --- a/test/api_integration/apis/index.js +++ b/test/api_integration/apis/index.js @@ -33,5 +33,6 @@ export default function({ loadTestFile }) { loadTestFile(require.resolve('./status')); loadTestFile(require.resolve('./stats')); loadTestFile(require.resolve('./ui_metric')); + loadTestFile(require.resolve('./telemetry')); }); } diff --git a/test/api_integration/apis/telemetry/index.js b/test/api_integration/apis/telemetry/index.js new file mode 100644 index 00000000000000..c79f5cb4708903 --- /dev/null +++ b/test/api_integration/apis/telemetry/index.js @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export default function({ loadTestFile }) { + describe('Telemetry', () => { + loadTestFile(require.resolve('./telemetry_local')); + loadTestFile(require.resolve('./opt_in')); + loadTestFile(require.resolve('./telemetry_optin_notice_seen')); + }); +} diff --git a/test/api_integration/apis/telemetry/opt_in.ts b/test/api_integration/apis/telemetry/opt_in.ts new file mode 100644 index 00000000000000..e4654ee3985f32 --- /dev/null +++ b/test/api_integration/apis/telemetry/opt_in.ts @@ -0,0 +1,123 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import expect from '@kbn/expect'; + +import { TelemetrySavedObjectAttributes } from 'src/plugins/telemetry/server/telemetry_repository'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function optInTest({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const kibanaServer = getService('kibanaServer'); + describe('/api/telemetry/v2/optIn API', () => { + let defaultAttributes: TelemetrySavedObjectAttributes; + let kibanaVersion: any; + before(async () => { + const kibanaVersionAccessor = kibanaServer.version; + kibanaVersion = await kibanaVersionAccessor.get(); + defaultAttributes = + (await getSavedObjectAttributes(supertest).catch(err => { + if (err.message === 'expected 200 "OK", got 404 "Not Found"') { + return null; + } + throw err; + })) || {}; + + expect(typeof kibanaVersion).to.eql('string'); + expect(kibanaVersion.length).to.be.greaterThan(0); + }); + + afterEach(async () => { + await updateSavedObjectAttributes(supertest, defaultAttributes); + }); + + it('should support sending false with allowChangingOptInStatus true', async () => { + await updateSavedObjectAttributes(supertest, { + ...defaultAttributes, + allowChangingOptInStatus: true, + }); + await postTelemetryV2Optin(supertest, false, 200); + const { enabled, lastVersionChecked } = await getSavedObjectAttributes(supertest); + expect(enabled).to.be(false); + expect(lastVersionChecked).to.be(kibanaVersion); + }); + + it('should support sending true with allowChangingOptInStatus true', async () => { + await updateSavedObjectAttributes(supertest, { + ...defaultAttributes, + allowChangingOptInStatus: true, + }); + await postTelemetryV2Optin(supertest, true, 200); + const { enabled, lastVersionChecked } = await getSavedObjectAttributes(supertest); + expect(enabled).to.be(true); + expect(lastVersionChecked).to.be(kibanaVersion); + }); + + it('should not support sending false with allowChangingOptInStatus false', async () => { + await updateSavedObjectAttributes(supertest, { + ...defaultAttributes, + allowChangingOptInStatus: false, + }); + await postTelemetryV2Optin(supertest, false, 400); + }); + + it('should not support sending true with allowChangingOptInStatus false', async () => { + await updateSavedObjectAttributes(supertest, { + ...defaultAttributes, + allowChangingOptInStatus: false, + }); + await postTelemetryV2Optin(supertest, true, 400); + }); + + it('should not support sending null', async () => { + await postTelemetryV2Optin(supertest, null, 400); + }); + + it('should not support sending junk', async () => { + await postTelemetryV2Optin(supertest, 42, 400); + }); + }); +} + +async function postTelemetryV2Optin(supertest: any, value: any, statusCode: number): Promise { + const { body } = await supertest + .post('/api/telemetry/v2/optIn') + .set('kbn-xsrf', 'xxx') + .send({ enabled: value }) + .expect(statusCode); + + return body; +} + +async function updateSavedObjectAttributes( + supertest: any, + attributes: TelemetrySavedObjectAttributes +): Promise { + return await supertest + .post('/api/saved_objects/telemetry/telemetry') + .query({ overwrite: true }) + .set('kbn-xsrf', 'xxx') + .send({ attributes }) + .expect(200); +} + +async function getSavedObjectAttributes(supertest: any): Promise { + const { body } = await supertest.get('/api/saved_objects/telemetry/telemetry').expect(200); + return body.attributes; +} diff --git a/test/api_integration/apis/telemetry/telemetry_local.js b/test/api_integration/apis/telemetry/telemetry_local.js new file mode 100644 index 00000000000000..84bfd8a755c116 --- /dev/null +++ b/test/api_integration/apis/telemetry/telemetry_local.js @@ -0,0 +1,133 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import expect from '@kbn/expect'; +import _ from 'lodash'; + +/* + * Create a single-level array with strings for all the paths to values in the + * source object, up to 3 deep. Going deeper than 3 causes a bit too much churn + * in the tests. + */ +function flatKeys(source) { + const recursivelyFlatKeys = (obj, path = [], depth = 0) => { + return depth < 3 && _.isObject(obj) + ? _.map(obj, (v, k) => recursivelyFlatKeys(v, [...path, k], depth + 1)) + : path.join('.'); + }; + + return _.uniq(_.flattenDeep(recursivelyFlatKeys(source))).sort((a, b) => a.localeCompare(b)); +} + +export default function({ getService }) { + const supertest = getService('supertest'); + + describe('/api/telemetry/v2/clusters/_stats', () => { + it('should pull local stats and validate data types', async () => { + const timeRange = { + min: '2018-07-23T22:07:00Z', + max: '2018-07-23T22:13:00Z', + }; + + const { body } = await supertest + .post('/api/telemetry/v2/clusters/_stats') + .set('kbn-xsrf', 'xxx') + .send({ timeRange, unencrypted: true }) + .expect(200); + + expect(body.length).to.be(1); + const stats = body[0]; + expect(stats.collection).to.be('local'); + expect(stats.stack_stats.kibana.count).to.be.a('number'); + expect(stats.stack_stats.kibana.indices).to.be.a('number'); + expect(stats.stack_stats.kibana.os.platforms[0].platform).to.be.a('string'); + expect(stats.stack_stats.kibana.os.platforms[0].count).to.be(1); + expect(stats.stack_stats.kibana.os.platformReleases[0].platformRelease).to.be.a('string'); + expect(stats.stack_stats.kibana.os.platformReleases[0].count).to.be(1); + expect(stats.stack_stats.kibana.plugins.telemetry.opt_in_status).to.be(false); + expect(stats.stack_stats.kibana.plugins.telemetry.usage_fetcher).to.be.a('string'); + expect(stats.stack_stats.kibana.plugins.stack_management).to.be.an('object'); + expect(stats.stack_stats.kibana.plugins.ui_metric).to.be.an('object'); + expect(stats.stack_stats.kibana.plugins.application_usage).to.be.an('object'); + expect(stats.stack_stats.kibana.plugins.kql.defaultQueryLanguage).to.be.a('string'); + expect(stats.stack_stats.kibana.plugins['tsvb-validation']).to.be.an('object'); + expect(stats.stack_stats.kibana.plugins.localization).to.be.an('object'); + expect(stats.stack_stats.kibana.plugins.csp.strict).to.be(true); + expect(stats.stack_stats.kibana.plugins.csp.warnLegacyBrowsers).to.be(true); + expect(stats.stack_stats.kibana.plugins.csp.rulesChangedFromDefault).to.be(false); + }); + + it('should pull local stats and validate fields', async () => { + const timeRange = { + min: '2018-07-23T22:07:00Z', + max: '2018-07-23T22:13:00Z', + }; + + const { body } = await supertest + .post('/api/telemetry/v2/clusters/_stats') + .set('kbn-xsrf', 'xxx') + .send({ timeRange, unencrypted: true }) + .expect(200); + + const stats = body[0]; + + const actual = flatKeys(stats); + expect(actual).to.be.an('array'); + const expected = [ + 'cluster_name', + 'cluster_stats.cluster_uuid', + 'cluster_stats.indices.analysis', + 'cluster_stats.indices.completion', + 'cluster_stats.indices.count', + 'cluster_stats.indices.docs', + 'cluster_stats.indices.fielddata', + 'cluster_stats.indices.mappings', + 'cluster_stats.indices.query_cache', + 'cluster_stats.indices.segments', + 'cluster_stats.indices.shards', + 'cluster_stats.indices.store', + 'cluster_stats.nodes.count', + 'cluster_stats.nodes.discovery_types', + 'cluster_stats.nodes.fs', + 'cluster_stats.nodes.ingest', + 'cluster_stats.nodes.jvm', + 'cluster_stats.nodes.network_types', + 'cluster_stats.nodes.os', + 'cluster_stats.nodes.packaging_types', + 'cluster_stats.nodes.plugins', + 'cluster_stats.nodes.process', + 'cluster_stats.nodes.versions', + 'cluster_stats.status', + 'cluster_stats.timestamp', + 'cluster_uuid', + 'collection', + 'collectionSource', + 'stack_stats.kibana.count', + 'stack_stats.kibana.indices', + 'stack_stats.kibana.os', + 'stack_stats.kibana.plugins', + 'stack_stats.kibana.versions', + 'timestamp', + 'version', + ]; + + expect(expected.every(m => actual.includes(m))).to.be.ok(); + }); + }); +} diff --git a/test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts b/test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts new file mode 100644 index 00000000000000..4413c672fb46c3 --- /dev/null +++ b/test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts @@ -0,0 +1,59 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import expect from '@kbn/expect'; +import { Client, DeleteDocumentParams, GetParams, GetResponse } from 'elasticsearch'; +import { TelemetrySavedObjectAttributes } from 'src/plugins/telemetry/server/telemetry_repository'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function optInTest({ getService }: FtrProviderContext) { + const client: Client = getService('legacyEs'); + const supertest = getService('supertest'); + + describe('/api/telemetry/v2/userHasSeenNotice API Telemetry User has seen OptIn Notice', () => { + it('should update telemetry setting field via PUT', async () => { + try { + await client.delete({ + index: '.kibana', + id: 'telemetry:telemetry', + } as DeleteDocumentParams); + } catch (err) { + if (err.statusCode !== 404) { + throw err; + } + } + + await supertest + .put('/api/telemetry/v2/userHasSeenNotice') + .set('kbn-xsrf', 'xxx') + .expect(200); + + const { + _source: { telemetry }, + }: GetResponse<{ + telemetry: TelemetrySavedObjectAttributes; + }> = await client.get({ + index: '.kibana', + id: 'telemetry:telemetry', + } as GetParams); + + expect(telemetry.userHasSeenNotice).to.be(true); + }); + }); +} From 3adab851380f4a368b9aa14cb227ef9f61e16e93 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Wed, 29 Apr 2020 13:01:23 -0500 Subject: [PATCH 23/26] Minimize dependencies required by our telemetry middleware (#64665) 1. we need our redux actions for our telemetry middleware, which: 2. require types from an index file, which: 3. includes all of our model types, and everything involved in them By moving these types to a separate file and importing _that_instead, we bypass inclusion of 2 and 3 in our plugin, which equates to ~550kB (of a total of ~600kB). --- .../siem/public/lib/telemetry/middleware.ts | 2 +- x-pack/plugins/siem/public/store/model.ts | 13 +------------ .../siem/public/store/timeline/actions.ts | 2 +- x-pack/plugins/siem/public/store/types.ts | 17 +++++++++++++++++ 4 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 x-pack/plugins/siem/public/store/types.ts diff --git a/x-pack/plugins/siem/public/lib/telemetry/middleware.ts b/x-pack/plugins/siem/public/lib/telemetry/middleware.ts index 59c6cb35669070..ca889e20e695f3 100644 --- a/x-pack/plugins/siem/public/lib/telemetry/middleware.ts +++ b/x-pack/plugins/siem/public/lib/telemetry/middleware.ts @@ -7,7 +7,7 @@ import { Action, Dispatch, MiddlewareAPI } from 'redux'; import { track, METRIC_TYPE, TELEMETRY_EVENT } from './'; -import { timelineActions } from '../../store/actions'; +import * as timelineActions from '../../store/timeline/actions'; export const telemetryMiddleware = (api: MiddlewareAPI) => (next: Dispatch) => (action: Action) => { if (timelineActions.endTimelineSaving.match(action)) { diff --git a/x-pack/plugins/siem/public/store/model.ts b/x-pack/plugins/siem/public/store/model.ts index 9e9e663a59fe09..686dc096e61b01 100644 --- a/x-pack/plugins/siem/public/store/model.ts +++ b/x-pack/plugins/siem/public/store/model.ts @@ -9,15 +9,4 @@ export { dragAndDropModel } from './drag_and_drop'; export { hostsModel } from './hosts'; export { inputsModel } from './inputs'; export { networkModel } from './network'; - -export type KueryFilterQueryKind = 'kuery' | 'lucene'; - -export interface KueryFilterQuery { - kind: KueryFilterQueryKind; - expression: string; -} - -export interface SerializedFilterQuery { - kuery: KueryFilterQuery | null; - serializedQuery: string; -} +export * from './types'; diff --git a/x-pack/plugins/siem/public/store/timeline/actions.ts b/x-pack/plugins/siem/public/store/timeline/actions.ts index a03cc2643e014a..12155decf40d44 100644 --- a/x-pack/plugins/siem/public/store/timeline/actions.ts +++ b/x-pack/plugins/siem/public/store/timeline/actions.ts @@ -12,7 +12,7 @@ import { DataProvider, QueryOperator, } from '../../components/timeline/data_providers/data_provider'; -import { KueryFilterQuery, SerializedFilterQuery } from '../model'; +import { KueryFilterQuery, SerializedFilterQuery } from '../types'; import { EventType, KqlMode, TimelineModel, ColumnHeaderOptions } from './model'; import { TimelineNonEcsData } from '../../graphql/types'; diff --git a/x-pack/plugins/siem/public/store/types.ts b/x-pack/plugins/siem/public/store/types.ts new file mode 100644 index 00000000000000..2c679ba41116ee --- /dev/null +++ b/x-pack/plugins/siem/public/store/types.ts @@ -0,0 +1,17 @@ +/* + * 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 type KueryFilterQueryKind = 'kuery' | 'lucene'; + +export interface KueryFilterQuery { + kind: KueryFilterQueryKind; + expression: string; +} + +export interface SerializedFilterQuery { + kuery: KueryFilterQuery | null; + serializedQuery: string; +} From 53ff22997a1401ccbd2808831b26b92fa174de92 Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Wed, 29 Apr 2020 14:06:08 -0400 Subject: [PATCH 24/26] [EPM] Update UI to handle package versions and updates (#64689) * link to installed version of detail page * add latestVersion property to EPM get package endpoint * add updates available notices * add update package button * handle various states and send installedVersion from package endpoint * fix type errors * fix install error because not returning promises * track version in state * handle unsuccessful update attempt * remove unused variable --- .../common/services/package_to_config.test.ts | 1 + .../ingest_manager/common/types/models/epm.ts | 2 + .../sections/epm/components/icons.tsx | 15 ++ .../sections/epm/components/package_card.tsx | 8 +- .../epm/hooks/use_package_install.tsx | 63 +++-- .../sections/epm/screens/detail/content.tsx | 3 +- .../epm/screens/detail/data_sources_panel.tsx | 2 +- .../sections/epm/screens/detail/header.tsx | 17 +- .../sections/epm/screens/detail/index.tsx | 4 +- .../screens/detail/installation_button.tsx | 23 +- .../epm/screens/detail/settings_panel.tsx | 236 ++++++++++++------ .../epm/screens/detail/side_nav_links.tsx | 2 +- .../server/services/epm/packages/get.ts | 4 +- .../server/services/epm/packages/index.ts | 1 + .../server/services/epm/packages/install.ts | 2 +- .../server/services/epm/packages/remove.ts | 8 +- 16 files changed, 277 insertions(+), 114 deletions(-) create mode 100644 x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/icons.tsx diff --git a/x-pack/plugins/ingest_manager/common/services/package_to_config.test.ts b/x-pack/plugins/ingest_manager/common/services/package_to_config.test.ts index cb290e61b17e51..a977a1a66e059a 100644 --- a/x-pack/plugins/ingest_manager/common/services/package_to_config.test.ts +++ b/x-pack/plugins/ingest_manager/common/services/package_to_config.test.ts @@ -11,6 +11,7 @@ describe('Ingest Manager - packageToConfig', () => { name: 'mock-package', title: 'Mock package', version: '0.0.0', + latestVersion: '0.0.0', description: 'description', type: 'mock', categories: [], diff --git a/x-pack/plugins/ingest_manager/common/types/models/epm.ts b/x-pack/plugins/ingest_manager/common/types/models/epm.ts index 05e160cdfb81ac..f8779a879a049f 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/epm.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/epm.ts @@ -204,6 +204,8 @@ export interface RegistryVarsEntry { // internal until we need them interface PackageAdditions { title: string; + latestVersion: string; + installedVersion?: string; assets: AssetsGroupedByServiceByType; } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/icons.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/icons.tsx new file mode 100644 index 00000000000000..64223efefaab8c --- /dev/null +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/icons.tsx @@ -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. + */ +import { EuiIcon } from '@elastic/eui'; +import React from 'react'; +import styled from 'styled-components'; + +export const StyledAlert = styled(EuiIcon)` + color: ${props => props.theme.eui.euiColorWarning}; + padding: 0 5px; +`; + +export const UpdateIcon = () => ; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/package_card.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/package_card.tsx index 8ad081cbbabe40..ab7e87b3ad06cb 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/package_card.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/components/package_card.tsx @@ -30,9 +30,15 @@ export function PackageCard({ showInstalledBadge, status, icons, + ...restProps }: PackageCardProps) { const { toDetailView } = useLinks(); - const url = toDetailView({ name, version }); + let urlVersion = version; + // if this is an installed package, link to the version installed + if ('savedObject' in restProps) { + urlVersion = restProps.savedObject.attributes.version || version; + } + const url = toDetailView({ name, version: urlVersion }); return ( ; +type InstallPackageProps = Pick & { + fromUpdate?: boolean; +}; +type SetPackageInstallStatusProps = Pick & PackageInstallItem; function usePackageInstall({ notifications }: { notifications: NotificationsStart }) { + const { toDetailView } = useLinks(); const [packages, setPackage] = useState({}); const setPackageInstallStatus = useCallback( - ({ name, status }: { name: PackageInfo['name']; status: InstallStatus }) => { + ({ name, status, version }: SetPackageInstallStatusProps) => { + const packageProps: PackageInstallItem = { + status, + version, + }; setPackage((prev: PackagesInstall) => ({ ...prev, - [name]: { status }, + [name]: packageProps, })); }, [] ); + const getPackageInstallStatus = useCallback( + (pkg: string): PackageInstallItem => { + return packages[pkg]; + }, + [packages] + ); + const installPackage = useCallback( - async ({ name, version, title }: InstallPackageProps) => { - setPackageInstallStatus({ name, status: InstallStatus.installing }); + async ({ name, version, title, fromUpdate = false }: InstallPackageProps) => { + const currStatus = getPackageInstallStatus(name); + const newStatus = { ...currStatus, name, status: InstallStatus.installing }; + setPackageInstallStatus(newStatus); const pkgkey = `${name}-${version}`; const res = await sendInstallPackage(pkgkey); if (res.error) { - setPackageInstallStatus({ name, status: InstallStatus.notInstalled }); + if (fromUpdate) { + // if there is an error during update, set it back to the previous version + // as handling of bad update is not implemented yet + setPackageInstallStatus({ ...currStatus, name }); + } else { + setPackageInstallStatus({ name, status: InstallStatus.notInstalled, version }); + } notifications.toasts.addWarning({ title: toMountPoint( { - return packages[pkg].status; - }, - [packages] + [getPackageInstallStatus, notifications.toasts, setPackageInstallStatus, toDetailView] ); const uninstallPackage = useCallback( async ({ name, version, title }: Pick) => { - setPackageInstallStatus({ name, status: InstallStatus.uninstalling }); + setPackageInstallStatus({ name, status: InstallStatus.uninstalling, version }); const pkgkey = `${name}-${version}`; const res = await sendRemovePackage(pkgkey); if (res.error) { - setPackageInstallStatus({ name, status: InstallStatus.installed }); + setPackageInstallStatus({ name, status: InstallStatus.installed, version }); notifications.toasts.addWarning({ title: toMountPoint( ; export function ContentPanel(props: ContentPanelProps) { - const { panel, name, version, assets, title, removable } = props; + const { panel, name, version, assets, title, removable, latestVersion } = props; switch (panel) { case 'settings': return ( @@ -60,6 +60,7 @@ export function ContentPanel(props: ContentPanelProps) { assets={assets} title={title} removable={removable} + latestVersion={latestVersion} /> ); case 'data-sources': diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/data_sources_panel.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/data_sources_panel.tsx index fa3245aec02c5b..c82b7ed2297a7c 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/data_sources_panel.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/data_sources_panel.tsx @@ -20,7 +20,7 @@ export const DataSourcesPanel = ({ name, version }: DataSourcesPanelProps) => { const packageInstallStatus = getPackageInstallStatus(name); // if they arrive at this page and the package is not installed, send them to overview // this happens if they arrive with a direct url or they uninstall while on this tab - if (packageInstallStatus !== InstallStatus.installed) + if (packageInstallStatus.status !== InstallStatus.installed) return ( props.theme.eui.euiSizeM}; `; -const StyledVersion = styled(Version)` - font-size: ${props => props.theme.eui.euiFontSizeS}; - color: ${props => props.theme.eui.euiColorDarkShade}; -`; - type HeaderProps = PackageInfo & { iconType?: IconType }; export function Header(props: HeaderProps) { - const { iconType, name, title, version } = props; + const { iconType, name, title, version, installedVersion, latestVersion } = props; const hasWriteCapabilites = useCapabilities().write; const { toListView } = useLinks(); const ADD_DATASOURCE_URI = useLink(`${EPM_PATH}/${name}-${version}/add-datasource`); - + const updateAvailable = installedVersion && installedVersion < latestVersion ? true : false; return ( @@ -59,7 +54,11 @@ export function Header(props: HeaderProps) {

{title} - + + + {version} {updateAvailable && } + +

diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/index.tsx index 3239d7b90e3c3c..1f3eb2cc9362e5 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/index.tsx @@ -32,11 +32,12 @@ export function Detail() { const packageInfo = response.data?.response; const title = packageInfo?.title; const name = packageInfo?.name; + const installedVersion = packageInfo?.installedVersion; const status: InstallStatus = packageInfo?.status as any; // track install status state if (name) { - setPackageInstallStatus({ name, status }); + setPackageInstallStatus({ name, status, version: installedVersion || null }); } if (packageInfo) { setInfo({ ...packageInfo, title: title || '' }); @@ -64,7 +65,6 @@ type LayoutProps = PackageInfo & Pick & Pick diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/installation_button.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/installation_button.tsx index cbbf1ce53c4ea3..cdad67fd875483 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/installation_button.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/installation_button.tsx @@ -13,19 +13,21 @@ import { ConfirmPackageUninstall } from './confirm_package_uninstall'; import { ConfirmPackageInstall } from './confirm_package_install'; type InstallationButtonProps = Pick & { - disabled: boolean; + disabled?: boolean; + isUpdate?: boolean; }; export function InstallationButton(props: InstallationButtonProps) { - const { assets, name, title, version, disabled = true } = props; + const { assets, name, title, version, disabled = true, isUpdate = false } = props; const hasWriteCapabilites = useCapabilities().write; const installPackage = useInstallPackage(); const uninstallPackage = useUninstallPackage(); const getPackageInstallStatus = useGetPackageInstallStatus(); - const installationStatus = getPackageInstallStatus(name); + const { status: installationStatus } = getPackageInstallStatus(name); const isInstalling = installationStatus === InstallStatus.installing; const isRemoving = installationStatus === InstallStatus.uninstalling; const isInstalled = installationStatus === InstallStatus.installed; + const showUninstallButton = isInstalled || isRemoving; const [isModalVisible, setModalVisible] = useState(false); const toggleModal = useCallback(() => { setModalVisible(!isModalVisible); @@ -36,6 +38,10 @@ export function InstallationButton(props: InstallationButtonProps) { toggleModal(); }, [installPackage, name, title, toggleModal, version]); + const handleClickUpdate = useCallback(() => { + installPackage({ name, version, title, fromUpdate: true }); + }, [installPackage, name, title, version]); + const handleClickUninstall = useCallback(() => { uninstallPackage({ name, version, title }); toggleModal(); @@ -78,6 +84,15 @@ export function InstallationButton(props: InstallationButtonProps) { ); + const updateButton = ( + + + + ); + const uninstallButton = ( - {isInstalled || isRemoving ? uninstallButton : installButton} + {isUpdate ? updateButton : showUninstallButton ? uninstallButton : installButton} {isModalVisible && (isInstalled ? uninstallModal : installModal)} ) : null; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx index 3589a1a9444e1b..4d4dba2a64e5a6 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx @@ -8,11 +8,22 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { EuiSpacer } from '@elastic/eui'; +import styled from 'styled-components'; import { InstallStatus, PackageInfo } from '../../../../types'; import { useGetDatasources } from '../../../../hooks'; import { DATASOURCE_SAVED_OBJECT_TYPE } from '../../../../constants'; import { useGetPackageInstallStatus } from '../../hooks'; import { InstallationButton } from './installation_button'; +import { UpdateIcon } from '../../components/icons'; + +const SettingsTitleCell = styled.td` + padding-right: ${props => props.theme.eui.spacerSizes.xl}; + padding-bottom: ${props => props.theme.eui.spacerSizes.m}; +`; + +const UpdatesAvailableMsgContainer = styled.span` + padding-left: ${props => props.theme.eui.spacerSizes.s}; +`; const NoteLabel = () => ( ( defaultMessage="Note:" /> ); +const UpdatesAvailableMsg = () => ( + + + + +); + export const SettingsPanel = ( - props: Pick + props: Pick ) => { + const { name, title, removable, latestVersion, version } = props; const getPackageInstallStatus = useGetPackageInstallStatus(); const { data: datasourcesData } = useGetDatasources({ perPage: 0, page: 1, kuery: `${DATASOURCE_SAVED_OBJECT_TYPE}.package.name:${props.name}`, }); - const { name, title, removable } = props; - const packageInstallStatus = getPackageInstallStatus(name); + const { status: installationStatus, version: installedVersion } = getPackageInstallStatus(name); const packageHasDatasources = !!datasourcesData?.total; + const updateAvailable = installedVersion && installedVersion < latestVersion ? true : false; + const isViewingOldPackage = version < latestVersion; + // hide install/remove options if the user has version of the package is installed + // and this package is out of date or if they do have a version installed but it's not this one + const hideInstallOptions = + (installationStatus === InstallStatus.notInstalled && isViewingOldPackage) || + (installationStatus === InstallStatus.installed && installedVersion !== version); + + const isUpdating = installationStatus === InstallStatus.installing && installedVersion; return ( @@ -43,14 +73,13 @@ export const SettingsPanel = ( - {packageInstallStatus === InstallStatus.notInstalled || - packageInstallStatus === InstallStatus.installing ? ( + {installedVersion !== null && (

-

- -

+ + + + + + + + + + + + + + + +
+ + {installedVersion} + + {updateAvailable && } +
+ + {latestVersion} + +
+ {updateAvailable && ( +

+ +

+ )}

- ) : ( + )} + {!hideInstallOptions && !isUpdating && (
- -

+ + {installationStatus === InstallStatus.notInstalled || + installationStatus === InstallStatus.installing ? ( +
+ +

+ +

+
+ +

+ +

+
+ ) : ( +
+ +

+ +

+
+ +

+ +

+
+ )} + + +

+ +

+
+
+ {packageHasDatasources && removable === true && ( +

+ + + ), }} /> -

-
- -

- -

+

+ )} + {removable === false && ( +

+ + + + ), + }} + /> +

+ )}
)} - - -

- -

-
-
- {packageHasDatasources && removable === true && ( -

- - - - ), - }} - /> -

- )} - {removable === false && ( -

- - - - ), - }} - /> -

- )}
); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/side_nav_links.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/side_nav_links.tsx index 05729ccfc1af42..ab168ef1530bd6 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/side_nav_links.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/side_nav_links.tsx @@ -37,7 +37,7 @@ export function SideNavLinks({ name, version, active }: NavLinkProps) { : p.theme.eui.euiFontWeightRegular}; `; // don't display Data Sources tab if the package is not installed - if (packageInstallStatus !== InstallStatus.installed && panel === 'data-sources') + if (packageInstallStatus.status !== InstallStatus.installed && panel === 'data-sources') return null; return ( diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts index d76584225877c2..da8d79a04b97cd 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts @@ -67,9 +67,10 @@ export async function getPackageInfo(options: { pkgVersion: string; }): Promise { const { savedObjectsClient, pkgName, pkgVersion } = options; - const [item, savedObject, assets] = await Promise.all([ + const [item, savedObject, latestPackage, assets] = await Promise.all([ Registry.fetchInfo(pkgName, pkgVersion), getInstallationObject({ savedObjectsClient, pkgName }), + Registry.fetchFindLatestPackage(pkgName), Registry.getArchiveInfo(pkgName, pkgVersion), ] as const); // adding `as const` due to regression in TS 3.7.2 @@ -79,6 +80,7 @@ export async function getPackageInfo(options: { // add properties that aren't (or aren't yet) on Registry response const updated = { ...item, + latestVersion: latestPackage.version, title: item.title || nameAsTitle(item.name), assets: Registry.groupPathsByService(assets || []), }; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/index.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/index.ts index d49e0e661440f3..c67cccd044bf5e 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/index.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/index.ts @@ -43,6 +43,7 @@ export function createInstallableFrom( ? { ...from, status: InstallationStatus.installed, + installedVersion: savedObject.attributes.version, savedObject, } : { diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts index 06f3decdbbe6f2..8f51c4d78305c0 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts @@ -106,7 +106,7 @@ export async function installPackage(options: { try { await deleteKibanaSavedObjectsAssets(savedObjectsClient, installedPkg.attributes.installed); } catch (err) { - // some assets may not exist if deleting during a failed update + // log these errors, some assets may not exist if deleted during a failed update } } diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts index ac2c869f3b9e9f..befb4722b6504f 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/remove.ts @@ -121,8 +121,12 @@ export async function deleteKibanaSavedObjectsAssets( const deletePromises = installedObjects.map(({ id, type }) => { const assetType = type as AssetType; if (savedObjectTypes.includes(assetType)) { - savedObjectsClient.delete(assetType, id); + return savedObjectsClient.delete(assetType, id); } }); - await Promise.all(deletePromises); + try { + await Promise.all(deletePromises); + } catch (err) { + throw new Error('error deleting saved object asset'); + } } From f5a8d8e6c27958dacc16a36b24bded57b4313f9d Mon Sep 17 00:00:00 2001 From: Lee Drengenberg Date: Wed, 29 Apr 2020 19:05:45 +0000 Subject: [PATCH 25/26] make inserting timestamp with navigate methods optional with default true (#64655) --- test/functional/page_objects/common_page.ts | 23 +++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index 862e5127bb6704..93debdcc37f0ab 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -44,6 +44,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo ensureCurrentUrl: boolean; shouldLoginIfPrompted: boolean; useActualUrl: boolean; + insertTimestamp: boolean; } class CommonPage { @@ -65,7 +66,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo * Logins to Kibana as default user and navigates to provided app * @param appUrl Kibana URL */ - private async loginIfPrompted(appUrl: string) { + private async loginIfPrompted(appUrl: string, insertTimestamp: boolean) { let currentUrl = await browser.getCurrentUrl(); log.debug(`currentUrl = ${currentUrl}\n appUrl = ${appUrl}`); await testSubjects.find('kibanaChrome', 6 * defaultFindTimeout); // 60 sec waiting @@ -87,7 +88,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo '[data-test-subj="kibanaChrome"] nav:not(.ng-hide)', 6 * defaultFindTimeout ); - await browser.get(appUrl); + await browser.get(appUrl, insertTimestamp); currentUrl = await browser.getCurrentUrl(); log.debug(`Finished login process currentUrl = ${currentUrl}`); } @@ -95,7 +96,13 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo } private async navigate(navigateProps: NavigateProps) { - const { appConfig, ensureCurrentUrl, shouldLoginIfPrompted, useActualUrl } = navigateProps; + const { + appConfig, + ensureCurrentUrl, + shouldLoginIfPrompted, + useActualUrl, + insertTimestamp, + } = navigateProps; const appUrl = getUrl.noAuth(config.get('servers.kibana'), appConfig); await retry.try(async () => { @@ -111,7 +118,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo } const currentUrl = shouldLoginIfPrompted - ? await this.loginIfPrompted(appUrl) + ? await this.loginIfPrompted(appUrl, insertTimestamp) : await browser.getCurrentUrl(); if (ensureCurrentUrl && !currentUrl.includes(appUrl)) { @@ -134,6 +141,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo ensureCurrentUrl = true, shouldLoginIfPrompted = true, useActualUrl = false, + insertTimestamp = true, } = {} ) { const appConfig = { @@ -146,6 +154,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo ensureCurrentUrl, shouldLoginIfPrompted, useActualUrl, + insertTimestamp, }); } @@ -165,6 +174,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo ensureCurrentUrl = true, shouldLoginIfPrompted = true, useActualUrl = true, + insertTimestamp = true, } = {} ) { const appConfig = { @@ -178,6 +188,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo ensureCurrentUrl, shouldLoginIfPrompted, useActualUrl, + insertTimestamp, }); } @@ -208,7 +219,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo async navigateToApp( appName: string, - { basePath = '', shouldLoginIfPrompted = true, hash = '' } = {} + { basePath = '', shouldLoginIfPrompted = true, hash = '', insertTimestamp = true } = {} ) { let appUrl: string; if (config.has(['apps', appName])) { @@ -239,7 +250,7 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo log.debug('returned from get, calling refresh'); await browser.refresh(); let currentUrl = shouldLoginIfPrompted - ? await this.loginIfPrompted(appUrl) + ? await this.loginIfPrompted(appUrl, insertTimestamp) : await browser.getCurrentUrl(); if (currentUrl.includes('app/kibana')) { From 02ba5fcb131dc82c4d253a8e49e40d3d9e600037 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Wed, 29 Apr 2020 12:19:31 -0700 Subject: [PATCH 26/26] [Reporting/Test] Convert functional test code to Typescript (#64601) * Convert the tests to typescript * remove outdated comment * fix typescript * fix "as any" Co-authored-by: Elastic Machine --- .../reporting/{index.js => index.ts} | 9 ++--- .../lib/{compare_pngs.js => compare_pngs.ts} | 13 ++++--- .../discover/{reporting.js => reporting.ts} | 3 +- .../visualize/{reporting.js => reporting.ts} | 3 +- x-pack/test/functional/page_objects/index.ts | 1 - .../{reporting_page.js => reporting_page.ts} | 35 ++++++++----------- 6 files changed, 33 insertions(+), 31 deletions(-) rename x-pack/test/functional/apps/dashboard/reporting/{index.js => index.ts} (94%) rename x-pack/test/functional/apps/dashboard/reporting/lib/{compare_pngs.js => compare_pngs.ts} (90%) rename x-pack/test/functional/apps/discover/{reporting.js => reporting.ts} (96%) rename x-pack/test/functional/apps/visualize/{reporting.js => reporting.ts} (94%) rename x-pack/test/functional/page_objects/{reporting_page.js => reporting_page.ts} (84%) diff --git a/x-pack/test/functional/apps/dashboard/reporting/index.js b/x-pack/test/functional/apps/dashboard/reporting/index.ts similarity index 94% rename from x-pack/test/functional/apps/dashboard/reporting/index.js rename to x-pack/test/functional/apps/dashboard/reporting/index.ts index 99be084d80d74c..796e15b4e270f4 100644 --- a/x-pack/test/functional/apps/dashboard/reporting/index.js +++ b/x-pack/test/functional/apps/dashboard/reporting/index.ts @@ -5,9 +5,10 @@ */ import expect from '@kbn/expect'; -import path from 'path'; import fs from 'fs'; +import path from 'path'; import { promisify } from 'util'; +import { FtrProviderContext } from '../../../ftr_provider_context'; import { checkIfPngsMatch } from './lib/compare_pngs'; const writeFileAsync = promisify(fs.writeFile); @@ -15,7 +16,7 @@ const mkdirAsync = promisify(fs.mkdir); const REPORTS_FOLDER = path.resolve(__dirname, 'reports'); -export default function({ getService, getPageObjects }) { +export default function({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); const log = getService('log'); @@ -85,14 +86,14 @@ export default function({ getService, getPageObjects }) { describe('Preserve Layout', () => { it('matches baseline report', async function() { - const writeSessionReport = async (name, rawPdf, reportExt) => { + const writeSessionReport = async (name: string, rawPdf: Buffer, reportExt: string) => { const sessionDirectory = path.resolve(REPORTS_FOLDER, 'session'); await mkdirAsync(sessionDirectory, { recursive: true }); const sessionReportPath = path.resolve(sessionDirectory, `${name}.${reportExt}`); await writeFileAsync(sessionReportPath, rawPdf); return sessionReportPath; }; - const getBaselineReportPath = (fileName, reportExt) => { + const getBaselineReportPath = (fileName: string, reportExt: string) => { const baselineFolder = path.resolve(REPORTS_FOLDER, 'baseline'); const fullPath = path.resolve(baselineFolder, `${fileName}.${reportExt}`); log.debug(`getBaselineReportPath (${fullPath})`); diff --git a/x-pack/test/functional/apps/dashboard/reporting/lib/compare_pngs.js b/x-pack/test/functional/apps/dashboard/reporting/lib/compare_pngs.ts similarity index 90% rename from x-pack/test/functional/apps/dashboard/reporting/lib/compare_pngs.js rename to x-pack/test/functional/apps/dashboard/reporting/lib/compare_pngs.ts index 13c97a7fce7858..b2eb645c8372c0 100644 --- a/x-pack/test/functional/apps/dashboard/reporting/lib/compare_pngs.js +++ b/x-pack/test/functional/apps/dashboard/reporting/lib/compare_pngs.ts @@ -4,14 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import path from 'path'; -import fs from 'fs'; import { promisify } from 'bluebird'; +import fs from 'fs'; +import path from 'path'; import { comparePngs } from '../../../../../../../test/functional/services/lib/compare_pngs'; -const mkdirAsync = promisify(fs.mkdir); +const mkdirAsync = promisify(fs.mkdir); -export async function checkIfPngsMatch(actualpngPath, baselinepngPath, screenshotsDirectory, log) { +export async function checkIfPngsMatch( + actualpngPath: string, + baselinepngPath: string, + screenshotsDirectory: string, + log: any +) { log.debug(`checkIfpngsMatch: ${actualpngPath} vs ${baselinepngPath}`); // Copy the pngs into the screenshot session directory, as that's where the generated pngs will automatically be // stored. diff --git a/x-pack/test/functional/apps/discover/reporting.js b/x-pack/test/functional/apps/discover/reporting.ts similarity index 96% rename from x-pack/test/functional/apps/discover/reporting.js rename to x-pack/test/functional/apps/discover/reporting.ts index 4aa005fc2db553..7a33e7f5135d48 100644 --- a/x-pack/test/functional/apps/discover/reporting.js +++ b/x-pack/test/functional/apps/discover/reporting.ts @@ -5,8 +5,9 @@ */ import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; -export default function({ getService, getPageObjects }) { +export default function({ getService, getPageObjects }: FtrProviderContext) { const log = getService('log'); const esArchiver = getService('esArchiver'); const browser = getService('browser'); diff --git a/x-pack/test/functional/apps/visualize/reporting.js b/x-pack/test/functional/apps/visualize/reporting.ts similarity index 94% rename from x-pack/test/functional/apps/visualize/reporting.js rename to x-pack/test/functional/apps/visualize/reporting.ts index bc252e1ad4134b..5ef954e334d815 100644 --- a/x-pack/test/functional/apps/visualize/reporting.js +++ b/x-pack/test/functional/apps/visualize/reporting.ts @@ -5,8 +5,9 @@ */ import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; -export default function({ getService, getPageObjects }) { +export default function({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const browser = getService('browser'); const log = getService('log'); diff --git a/x-pack/test/functional/page_objects/index.ts b/x-pack/test/functional/page_objects/index.ts index 782d57adea7707..4b8c2944ef190f 100644 --- a/x-pack/test/functional/page_objects/index.ts +++ b/x-pack/test/functional/page_objects/index.ts @@ -19,7 +19,6 @@ import { GraphPageProvider } from './graph_page'; import { GrokDebuggerPageProvider } from './grok_debugger_page'; // @ts-ignore not ts yet import { WatcherPageProvider } from './watcher_page'; -// @ts-ignore not ts yet import { ReportingPageProvider } from './reporting_page'; // @ts-ignore not ts yet import { AccountSettingProvider } from './accountsetting_page'; diff --git a/x-pack/test/functional/page_objects/reporting_page.js b/x-pack/test/functional/page_objects/reporting_page.ts similarity index 84% rename from x-pack/test/functional/page_objects/reporting_page.js rename to x-pack/test/functional/page_objects/reporting_page.ts index b24ba8cf95d1ce..2c20519a8d2140 100644 --- a/x-pack/test/functional/page_objects/reporting_page.js +++ b/x-pack/test/functional/page_objects/reporting_page.ts @@ -4,25 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ +import http, { IncomingMessage } from 'http'; +import { FtrProviderContext } from 'test/functional/ftr_provider_context'; import { parse } from 'url'; -import http from 'http'; -/* - * NOTE: Reporting is a service, not an app. The page objects that are - * important for generating reports belong to the apps that integrate with the - * Reporting service. Eventually, this file should be dissolved across the - * apps that need it for testing their integration. - * Issue: https://github.com/elastic/kibana/issues/52927 - */ -export function ReportingPageProvider({ getService, getPageObjects }) { +export function ReportingPageProvider({ getService, getPageObjects }: FtrProviderContext) { const retry = getService('retry'); const log = getService('log'); const testSubjects = getService('testSubjects'); const browser = getService('browser'); - const PageObjects = getPageObjects(['common', 'security', 'share', 'timePicker']); + const PageObjects = getPageObjects(['common', 'security' as any, 'share', 'timePicker']); // FIXME: Security PageObject is not Typescript class ReportingPage { - async forceSharedItemsContainerSize({ width }) { + async forceSharedItemsContainerSize({ width }: { width: number }) { await browser.execute(` var el = document.querySelector('[data-shared-items-container]'); el.style.flex="none"; @@ -30,7 +24,7 @@ export function ReportingPageProvider({ getService, getPageObjects }) { `); } - async getReportURL(timeout) { + async getReportURL(timeout: number) { log.debug('getReportURL'); const url = await testSubjects.getAttribute('downloadCompletedReportButton', 'href', timeout); @@ -48,7 +42,7 @@ export function ReportingPageProvider({ getService, getPageObjects }) { `); } - getResponse(url) { + getResponse(url: string): Promise { log.debug(`getResponse for ${url}`); const auth = 'test_user:changeme'; // FIXME not sure why there is no config that can be read for this const headers = { @@ -62,29 +56,30 @@ export function ReportingPageProvider({ getService, getPageObjects }) { hostname: parsedUrl.hostname, path: parsedUrl.path, port: parsedUrl.port, - responseType: 'arraybuffer', headers, }, - res => { + (res: IncomingMessage) => { resolve(res); } ) - .on('error', e => { + .on('error', (e: Error) => { log.error(e); reject(e); }); }); } - async getRawPdfReportData(url) { - const data = []; // List of Buffer objects + async getRawPdfReportData(url: string): Promise { + const data: Buffer[] = []; // List of Buffer objects log.debug(`getRawPdfReportData for ${url}`); return new Promise(async (resolve, reject) => { const response = await this.getResponse(url).catch(reject); - response.on('data', chunk => data.push(chunk)); - response.on('end', () => resolve(Buffer.concat(data))); + if (response) { + response.on('data', (chunk: Buffer) => data.push(chunk)); + response.on('end', () => resolve(Buffer.concat(data))); + } }); }