diff --git a/src/dev/build/lib/fs.ts b/src/dev/build/lib/fs.ts index d86901c41e436..a91113ab2d1c4 100644 --- a/src/dev/build/lib/fs.ts +++ b/src/dev/build/lib/fs.ts @@ -273,7 +273,16 @@ export async function compressTar({ archive.pipe(output); - return archive.directory(source, name).finalize(); + let fileCount = 0; + archive.on('entry', (entry) => { + if (entry.stats?.isFile()) { + fileCount += 1; + } + }); + + await archive.directory(source, name).finalize(); + + return fileCount; } interface CompressZipOptions { @@ -294,5 +303,14 @@ export async function compressZip({ archive.pipe(output); - return archive.directory(source, name).finalize(); + let fileCount = 0; + archive.on('entry', (entry) => { + if (entry.stats?.isFile()) { + fileCount += 1; + } + }); + + await archive.directory(source, name).finalize(); + + return fileCount; } diff --git a/src/dev/build/tasks/create_archives_task.ts b/src/dev/build/tasks/create_archives_task.ts index 3ffb1afef7469..0083881e9f748 100644 --- a/src/dev/build/tasks/create_archives_task.ts +++ b/src/dev/build/tasks/create_archives_task.ts @@ -21,7 +21,7 @@ import Path from 'path'; import Fs from 'fs'; import { promisify } from 'util'; -import { CiStatsReporter } from '@kbn/dev-utils'; +import { CiStatsReporter, CiStatsMetrics } from '@kbn/dev-utils'; import { mkdirp, compressTar, compressZip, Task } from '../lib'; @@ -47,17 +47,16 @@ export const CreateArchives: Task = { archives.push({ format: 'zip', path: destination, - }); - - await compressZip({ - source, - destination, - archiverOptions: { - zlib: { - level: 9, + fileCount: await compressZip({ + source, + destination, + archiverOptions: { + zlib: { + level: 9, + }, }, - }, - createRootDirectory: true, + createRootDirectory: true, + }), }); break; @@ -65,18 +64,17 @@ export const CreateArchives: Task = { archives.push({ format: 'tar', path: destination, - }); - - await compressTar({ - source, - destination, - archiverOptions: { - gzip: true, - gzipOptions: { - level: 9, + fileCount: await compressTar({ + source, + destination, + archiverOptions: { + gzip: true, + gzipOptions: { + level: 9, + }, }, - }, - createRootDirectory: true, + createRootDirectory: true, + }), }); break; @@ -85,19 +83,22 @@ export const CreateArchives: Task = { } } - const reporter = CiStatsReporter.fromEnv(log); - if (reporter.isEnabled()) { - await reporter.metrics( - await Promise.all( - archives.map(async ({ format, path }) => { - return { - group: `${build.isOss() ? 'oss ' : ''}distributable size`, - id: format, - value: (await asyncStat(path)).size, - }; - }) - ) - ); + const metrics: CiStatsMetrics = []; + for (const { format, path, fileCount } of archives) { + metrics.push({ + group: `${build.isOss() ? 'oss ' : ''}distributable size`, + id: format, + value: (await asyncStat(path)).size, + }); + + metrics.push({ + group: `${build.isOss() ? 'oss ' : ''}distributable file count`, + id: 'total', + value: fileCount, + }); } + log.debug('archive metrics:', metrics); + + await CiStatsReporter.fromEnv(log).metrics(metrics); }, }; diff --git a/src/legacy/core_plugins/kibana/server/ui_setting_defaults.js b/src/legacy/core_plugins/kibana/server/ui_setting_defaults.js index 2562657a71624..7de5fb581643a 100644 --- a/src/legacy/core_plugins/kibana/server/ui_setting_defaults.js +++ b/src/legacy/core_plugins/kibana/server/ui_setting_defaults.js @@ -17,88 +17,7 @@ * under the License. */ -import { i18n } from '@kbn/i18n'; - export function getUiSettingDefaults() { // wrapped in provider so that a new instance is given to each app/test - return { - 'visualization:tileMap:maxPrecision': { - name: i18n.translate('kbn.advancedSettings.visualization.tileMap.maxPrecisionTitle', { - defaultMessage: 'Maximum tile map precision', - }), - value: 7, - description: i18n.translate('kbn.advancedSettings.visualization.tileMap.maxPrecisionText', { - defaultMessage: - 'The maximum geoHash precision displayed on tile maps: 7 is high, 10 is very high, 12 is the max. {cellDimensionsLink}', - description: - 'Part of composite text: kbn.advancedSettings.visualization.tileMap.maxPrecisionText + ' + - 'kbn.advancedSettings.visualization.tileMap.maxPrecision.cellDimensionsLinkText', - values: { - cellDimensionsLink: - `` + - i18n.translate( - 'kbn.advancedSettings.visualization.tileMap.maxPrecision.cellDimensionsLinkText', - { - defaultMessage: 'Explanation of cell dimensions', - } - ) + - '', - }, - }), - category: ['visualization'], - }, - 'visualization:tileMap:WMSdefaults': { - name: i18n.translate('kbn.advancedSettings.visualization.tileMap.wmsDefaultsTitle', { - defaultMessage: 'Default WMS properties', - }), - value: JSON.stringify( - { - enabled: false, - url: undefined, - options: { - version: undefined, - layers: undefined, - format: 'image/png', - transparent: true, - attribution: undefined, - styles: undefined, - }, - }, - null, - 2 - ), - type: 'json', - description: i18n.translate('kbn.advancedSettings.visualization.tileMap.wmsDefaultsText', { - defaultMessage: - 'Default {propertiesLink} for the WMS map server support in the coordinate map', - description: - 'Part of composite text: kbn.advancedSettings.visualization.tileMap.wmsDefaultsText + ' + - 'kbn.advancedSettings.visualization.tileMap.wmsDefaults.propertiesLinkText', - values: { - propertiesLink: - '' + - i18n.translate( - 'kbn.advancedSettings.visualization.tileMap.wmsDefaults.propertiesLinkText', - { - defaultMessage: 'properties', - } - ) + - '', - }, - }), - category: ['visualization'], - }, - 'visualization:regionmap:showWarnings': { - name: i18n.translate('kbn.advancedSettings.visualization.showRegionMapWarningsTitle', { - defaultMessage: 'Show region map warning', - }), - value: true, - description: i18n.translate('kbn.advancedSettings.visualization.showRegionMapWarningsText', { - defaultMessage: - 'Whether the region map shows a warning when terms cannot be joined to a shape on the map.', - }), - category: ['visualization'], - }, - }; + return {}; } diff --git a/src/plugins/maps_legacy/server/index.ts b/src/plugins/maps_legacy/server/index.ts index 5da3ce1a84408..79ecbb238314a 100644 --- a/src/plugins/maps_legacy/server/index.ts +++ b/src/plugins/maps_legacy/server/index.ts @@ -18,9 +18,10 @@ */ import { Plugin, PluginConfigDescriptor } from 'kibana/server'; -import { PluginInitializerContext } from 'src/core/server'; +import { CoreSetup, PluginInitializerContext } from 'src/core/server'; import { Observable } from 'rxjs'; import { configSchema, ConfigSchema } from '../config'; +import { getUiSettings } from './ui_settings'; export const config: PluginConfigDescriptor = { exposeToBrowser: { @@ -49,7 +50,9 @@ export class MapsLegacyPlugin implements Plugin { this._initializerContext = initializerContext; } - public setup() { + public setup(core: CoreSetup) { + core.uiSettings.register(getUiSettings()); + // @ts-ignore const config$ = this._initializerContext.config.create(); return { diff --git a/src/plugins/maps_legacy/server/ui_settings.ts b/src/plugins/maps_legacy/server/ui_settings.ts new file mode 100644 index 0000000000000..f92ccf848f409 --- /dev/null +++ b/src/plugins/maps_legacy/server/ui_settings.ts @@ -0,0 +1,113 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { UiSettingsParams } from 'kibana/server'; +import { schema } from '@kbn/config-schema'; + +export function getUiSettings(): Record> { + return { + 'visualization:tileMap:maxPrecision': { + name: i18n.translate('maps_legacy.advancedSettings.visualization.tileMap.maxPrecisionTitle', { + defaultMessage: 'Maximum tile map precision', + }), + value: 7, + description: i18n.translate( + 'maps_legacy.advancedSettings.visualization.tileMap.maxPrecisionText', + { + defaultMessage: + 'The maximum geoHash precision displayed on tile maps: 7 is high, 10 is very high, 12 is the max. {cellDimensionsLink}', + description: + 'Part of composite text: maps_legacy.advancedSettings.visualization.tileMap.maxPrecisionText + ' + + 'maps_legacy.advancedSettings.visualization.tileMap.maxPrecision.cellDimensionsLinkText', + values: { + cellDimensionsLink: + `` + + i18n.translate( + 'maps_legacy.advancedSettings.visualization.tileMap.maxPrecision.cellDimensionsLinkText', + { + defaultMessage: 'Explanation of cell dimensions', + } + ) + + '', + }, + } + ), + schema: schema.number(), + category: ['visualization'], + }, + 'visualization:tileMap:WMSdefaults': { + name: i18n.translate('maps_legacy.advancedSettings.visualization.tileMap.wmsDefaultsTitle', { + defaultMessage: 'Default WMS properties', + }), + value: JSON.stringify( + { + enabled: false, + url: '', + options: { + version: '', + layers: '', + format: 'image/png', + transparent: true, + attribution: '', + styles: '', + }, + }, + null, + 2 + ), + type: 'json', + description: i18n.translate( + 'maps_legacy.advancedSettings.visualization.tileMap.wmsDefaultsText', + { + defaultMessage: + 'Default {propertiesLink} for the WMS map server support in the coordinate map', + description: + 'Part of composite text: maps_legacy.advancedSettings.visualization.tileMap.wmsDefaultsText + ' + + 'maps_legacy.advancedSettings.visualization.tileMap.wmsDefaults.propertiesLinkText', + values: { + propertiesLink: + '' + + i18n.translate( + 'maps_legacy.advancedSettings.visualization.tileMap.wmsDefaults.propertiesLinkText', + { + defaultMessage: 'properties', + } + ) + + '', + }, + } + ), + schema: schema.object({ + enabled: schema.boolean(), + url: schema.string(), + options: schema.object({ + version: schema.string(), + layers: schema.string(), + format: schema.string(), + transparent: schema.boolean(), + attribution: schema.string(), + styles: schema.string(), + }), + }), + category: ['visualization'], + }, + }; +} diff --git a/src/plugins/region_map/server/index.ts b/src/plugins/region_map/server/index.ts index e2c544d2d0ba6..f4684e1c60349 100644 --- a/src/plugins/region_map/server/index.ts +++ b/src/plugins/region_map/server/index.ts @@ -18,7 +18,9 @@ */ import { PluginConfigDescriptor } from 'kibana/server'; +import { CoreSetup } from 'src/core/server'; import { configSchema, ConfigSchema } from '../config'; +import { getUiSettings } from './ui_settings'; export const config: PluginConfigDescriptor = { exposeToBrowser: { @@ -29,6 +31,9 @@ export const config: PluginConfigDescriptor = { }; export const plugin = () => ({ - setup() {}, + setup(core: CoreSetup) { + core.uiSettings.register(getUiSettings()); + }, + start() {}, }); diff --git a/src/plugins/region_map/server/ui_settings.ts b/src/plugins/region_map/server/ui_settings.ts new file mode 100644 index 0000000000000..9c404676b9ffd --- /dev/null +++ b/src/plugins/region_map/server/ui_settings.ts @@ -0,0 +1,42 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { UiSettingsParams } from 'kibana/server'; +import { schema } from '@kbn/config-schema'; + +export function getUiSettings(): Record> { + return { + 'visualization:regionmap:showWarnings': { + name: i18n.translate('regionMap.advancedSettings.visualization.showRegionMapWarningsTitle', { + defaultMessage: 'Show region map warning', + }), + value: true, + description: i18n.translate( + 'regionMap.advancedSettings.visualization.showRegionMapWarningsText', + { + defaultMessage: + 'Whether the region map shows a warning when terms cannot be joined to a shape on the map.', + } + ), + schema: schema.boolean(), + category: ['visualization'], + }, + }; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx index 654f4dce0ebf3..a0d9352ee9f82 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx @@ -12,8 +12,8 @@ import { Redirect } from 'react-router-dom'; import { shallow } from 'enzyme'; import { useValues } from 'kea'; -import { Overview } from './components/overview'; -import { ErrorState } from './components/error_state'; +import { Overview } from './views/overview'; +import { ErrorState } from './views/error_state'; import { WorkplaceSearch } from './'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx index b261c83e30dde..8582a003c6fa8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx @@ -16,11 +16,11 @@ import { WorkplaceSearchNav } from './components/layout/nav'; import { SETUP_GUIDE_PATH } from './routes'; -import { SetupGuide } from './components/setup_guide'; -import { ErrorState } from './components/error_state'; -import { Overview } from './components/overview'; +import { SetupGuide } from './views/setup_guide'; +import { ErrorState } from './views/error_state'; +import { Overview } from './views/overview'; -export const WorkplaceSearch: React.FC = (props) => { +export const WorkplaceSearch: React.FC = () => { const { config } = useContext(KibanaContext) as IKibanaContext; const { errorConnecting } = useValues(HttpLogic) as IHttpLogicValues; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx similarity index 93% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx index 53f3a7a274429..9ad649c292fb7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/error_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx @@ -13,7 +13,7 @@ import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; import { ErrorStatePrompt } from '../../../shared/error_state'; import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; -import { ViewContentHeader } from '../shared/view_content_header'; +import { ViewContentHeader } from '../../components/shared/view_content_header'; export const ErrorState: React.FC = () => { return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/index.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/error_state/index.ts rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/__mocks__/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/index.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/__mocks__/index.ts rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/__mocks__/overview_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/__mocks__/overview_logic.mock.ts rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/index.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/index.ts rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_card.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_card.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx index d0f5893bdb88a..fa4decccb34b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/onboarding_steps.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx @@ -21,12 +21,12 @@ import { EuiButtonEmptyProps, EuiLinkProps, } from '@elastic/eui'; -import sharedSourcesIcon from '../shared/assets/share_circle.svg'; +import sharedSourcesIcon from '../../components/shared/assets/share_circle.svg'; import { sendTelemetry } from '../../../shared/telemetry'; import { KibanaContext, IKibanaContext } from '../../../index'; import { ORG_SOURCES_PATH, USERS_PATH, ORG_SETTINGS_PATH } from '../../routes'; -import { ContentSection } from '../shared/content_section'; +import { ContentSection } from '../../components/shared/content_section'; import { OverviewLogic, IOverviewValues } from './overview_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/organization_stats.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/organization_stats.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/organization_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.tsx similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/organization_stats.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.tsx index 4c5efce9baf12..53549cfcdbce7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/organization_stats.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.tsx @@ -11,7 +11,7 @@ import { useValues } from 'kea'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { ContentSection } from '../shared/content_section'; +import { ContentSection } from '../../components/shared/content_section'; import { ORG_SOURCES_PATH, USERS_PATH } from '../../routes'; import { OverviewLogic, IOverviewValues } from './overview_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx similarity index 93% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx index fee966a56923d..e4531ff03587b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx @@ -11,8 +11,8 @@ import { mockLogicActions, setMockValues } from './__mocks__'; import React from 'react'; import { shallow, mount } from 'enzyme'; -import { Loading } from '../shared/loading'; -import { ViewContentHeader } from '../shared/view_content_header'; +import { Loading } from '../../components/shared/loading'; +import { ViewContentHeader } from '../../components/shared/view_content_header'; import { OnboardingSteps } from './onboarding_steps'; import { OrganizationStats } from './organization_stats'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.tsx similarity index 93% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.tsx index 6aa3e1e608bfe..134fc9389694d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.tsx @@ -16,9 +16,9 @@ import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/t import { OverviewLogic, IOverviewActions, IOverviewValues } from './overview_logic'; -import { Loading } from '../shared/loading'; -import { ProductButton } from '../shared/product_button'; -import { ViewContentHeader } from '../shared/view_content_header'; +import { Loading } from '../../components/shared/loading'; +import { ProductButton } from '../../components/shared/product_button'; +import { ViewContentHeader } from '../../components/shared/view_content_header'; import { OnboardingSteps } from './onboarding_steps'; import { OrganizationStats } from './organization_stats'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/overview_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/recent_activity.scss b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.scss similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/recent_activity.scss rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.scss diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/recent_activity.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/recent_activity.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/recent_activity.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx similarity index 98% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/recent_activity.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx index 0f4f6c65d083c..ada89c33be7e2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/recent_activity.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx @@ -12,7 +12,7 @@ import { useValues } from 'kea'; import { EuiEmptyPrompt, EuiLink, EuiPanel, EuiSpacer, EuiLinkProps } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ContentSection } from '../shared/content_section'; +import { ContentSection } from '../../components/shared/content_section'; import { sendTelemetry } from '../../../shared/telemetry'; import { KibanaContext, IKibanaContext } from '../../../index'; import { getSourcePath } from '../../routes'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/statistic_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/statistic_card.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/statistic_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/overview/statistic_card.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/index.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/index.ts rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/index.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.test.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/workplace_search/components/setup_guide/setup_guide.tsx rename to x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx index 8291b673cd17a..f17bf172b0fb1 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx @@ -84,6 +84,7 @@ const initialState: IndexPatternPrivateState = { id: '1', title: 'idx1', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', @@ -134,6 +135,7 @@ const initialState: IndexPatternPrivateState = { id: '2', title: 'idx2', timeFieldName: 'timestamp', + hasRestrictions: true, fields: [ { name: 'timestamp', @@ -191,6 +193,7 @@ const initialState: IndexPatternPrivateState = { id: '3', title: 'idx3', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', @@ -322,8 +325,20 @@ describe('IndexPattern Data Panel', () => { isFirstExistenceFetch: false, currentIndexPatternId: 'a', indexPatterns: { - a: { id: 'a', title: 'aaa', timeFieldName: 'atime', fields: [] }, - b: { id: 'b', title: 'bbb', timeFieldName: 'btime', fields: [] }, + a: { + id: 'a', + title: 'aaa', + timeFieldName: 'atime', + fields: [], + hasRestrictions: false, + }, + b: { + id: 'b', + title: 'bbb', + timeFieldName: 'btime', + fields: [], + hasRestrictions: false, + }, }, layers: { 1: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx index 0777b9b9d8e57..f7adf91e307da 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx @@ -126,6 +126,7 @@ export function IndexPatternDataPanel({ title: indexPatterns[id].title, timeFieldName: indexPatterns[id].timeFieldName, fields: indexPatterns[id].fields, + hasRestrictions: indexPatterns[id].hasRestrictions, })); const dslQuery = buildSafeEsQuery( @@ -422,6 +423,8 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ ] ); + const fieldInfoUnavailable = existenceFetchFailed || currentIndexPattern.hasRestrictions; + return ( - {!existenceFetchFailed && ( + {!fieldInfoUnavailable && ( { foo: { id: 'foo', title: 'Foo pattern', + hasRestrictions: false, fields: [ { aggregatable: true, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx index b2a59788b50f9..e4dfa69813743 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx @@ -181,7 +181,7 @@ export function FieldSelect({ }} renderOption={(option, searchValue) => { return ( - + ( - + ), - [fieldProps, exists] + [fieldProps, exists, hideDetails] ); return ( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts index 0ba7b7df97853..900cd02622aaf 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts @@ -21,6 +21,7 @@ const expectedIndexPatterns = { id: '1', title: 'my-fake-index-pattern', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', @@ -70,6 +71,7 @@ const expectedIndexPatterns = { id: '2', title: 'my-fake-restricted-pattern', timeFieldName: 'timestamp', + hasRestrictions: true, fields: [ { name: 'timestamp', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx index 5489dcffc52c4..663d7c18bb370 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx @@ -20,6 +20,7 @@ const expectedIndexPatterns = { id: '1', title: 'my-fake-index-pattern', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', @@ -68,6 +69,7 @@ const expectedIndexPatterns = { 2: { id: '2', title: 'my-fake-restricted-pattern', + hasRestrictions: true, timeFieldName: 'timestamp', fields: [ { @@ -322,6 +324,7 @@ describe('IndexPattern Data Source suggestions', () => { 1: { id: '1', title: 'no timefield', + hasRestrictions: false, fields: [ { name: 'bytes', @@ -532,6 +535,7 @@ describe('IndexPattern Data Source suggestions', () => { 1: { id: '1', title: 'no timefield', + hasRestrictions: false, fields: [ { name: 'bytes', @@ -1350,6 +1354,7 @@ describe('IndexPattern Data Source suggestions', () => { 1: { id: '1', title: 'my-fake-index-pattern', + hasRestrictions: false, fields: [ { name: 'field1', @@ -1493,6 +1498,7 @@ describe('IndexPattern Data Source suggestions', () => { 1: { id: '1', title: 'my-fake-index-pattern', + hasRestrictions: false, fields: [ { name: 'field1', @@ -1555,6 +1561,7 @@ describe('IndexPattern Data Source suggestions', () => { 1: { id: '1', title: 'my-fake-index-pattern', + hasRestrictions: false, fields: [ { name: 'field1', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx index 738cdd611a7ba..92e35b257f24a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx @@ -62,6 +62,7 @@ const initialState: IndexPatternPrivateState = { id: '1', title: 'my-fake-index-pattern', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', @@ -103,6 +104,7 @@ const initialState: IndexPatternPrivateState = { '2': { id: '2', title: 'my-fake-restricted-pattern', + hasRestrictions: true, timeFieldName: 'timestamp', fields: [ { @@ -160,6 +162,7 @@ const initialState: IndexPatternPrivateState = { id: '3', title: 'my-compatible-pattern', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts index d80bf779a5d17..660be9514a92f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts @@ -40,6 +40,7 @@ const indexPattern1 = ({ id: '1', title: 'my-fake-index-pattern', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', @@ -105,6 +106,7 @@ const indexPattern2 = ({ id: '2', title: 'my-fake-restricted-pattern', timeFieldName: 'timestamp', + hasRestrictions: true, fields: [ { name: 'timestamp', @@ -733,9 +735,9 @@ describe('loader', () => { dateRange: { fromDate: '1900-01-01', toDate: '2000-01-01' }, fetchJson, indexPatterns: [ - { id: '1', title: '1', fields: [] }, - { id: '2', title: '1', fields: [] }, - { id: '3', title: '1', fields: [] }, + { id: '1', title: '1', fields: [], hasRestrictions: false }, + { id: '2', title: '1', fields: [], hasRestrictions: false }, + { id: '3', title: '1', fields: [], hasRestrictions: false }, ], setState, dslQuery, @@ -783,9 +785,9 @@ describe('loader', () => { dateRange: { fromDate: '1900-01-01', toDate: '2000-01-01' }, fetchJson, indexPatterns: [ - { id: '1', title: '1', fields: [] }, - { id: '2', title: '1', fields: [] }, - { id: 'c', title: '1', fields: [] }, + { id: '1', title: '1', fields: [], hasRestrictions: false }, + { id: '2', title: '1', fields: [], hasRestrictions: false }, + { id: 'c', title: '1', fields: [], hasRestrictions: false }, ], setState, dslQuery, @@ -817,6 +819,7 @@ describe('loader', () => { { id: '1', title: '1', + hasRestrictions: false, fields: [{ name: 'field1' }, { name: 'field2' }] as IndexPatternField[], }, ], diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts index 24906790a9fc9..585a1281cbf51 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts @@ -91,6 +91,7 @@ export async function loadIndexPatterns({ timeFieldName, fieldFormatMap, fields: newFields, + hasRestrictions: !!typeMeta?.aggs, }; return { @@ -334,6 +335,7 @@ export async function syncExistingFields({ title: string; fields: IndexPatternField[]; timeFieldName?: string | null; + hasRestrictions: boolean; }>; fetchJson: HttpSetup['post']; setState: SetState; @@ -343,6 +345,12 @@ export async function syncExistingFields({ showNoDataPopover: () => void; }) { const existenceRequests = indexPatterns.map((pattern) => { + if (pattern.hasRestrictions) { + return { + indexPatternTitle: pattern.title, + existingFieldNames: pattern.fields.map((field) => field.name), + }; + } const body: Record = { dslQuery, fromDate: dateRange.fromDate, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts b/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts index 869eee67d381d..31e6240993d36 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts @@ -11,6 +11,7 @@ export const createMockedIndexPattern = (): IndexPattern => ({ id: '1', title: 'my-fake-index-pattern', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', @@ -70,6 +71,7 @@ export const createMockedRestrictedIndexPattern = () => ({ id: '2', title: 'my-fake-restricted-pattern', timeFieldName: 'timestamp', + hasRestrictions: true, fields: [ { name: 'timestamp', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx index 48a6079c58ac0..ac6bf63c37110 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx @@ -55,6 +55,7 @@ describe('date_histogram', () => { id: '1', title: 'Mock Indexpattern', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', @@ -69,6 +70,7 @@ describe('date_histogram', () => { 2: { id: '2', title: 'Mock Indexpattern 2', + hasRestrictions: false, fields: [ { name: 'other_timestamp', @@ -229,13 +231,50 @@ describe('date_histogram', () => { it('should reflect params correctly', () => { const esAggsConfig = dateHistogramOperation.toEsAggsConfig( state.layers.first.columns.col1 as DateHistogramIndexPatternColumn, - 'col1' + 'col1', + state.indexPatterns['1'] ); expect(esAggsConfig).toEqual( expect.objectContaining({ params: expect.objectContaining({ interval: '42w', field: 'timestamp', + useNormalizedEsInterval: true, + }), + }) + ); + }); + + it('should not use normalized es interval for rollups', () => { + const esAggsConfig = dateHistogramOperation.toEsAggsConfig( + state.layers.first.columns.col1 as DateHistogramIndexPatternColumn, + 'col1', + { + ...state.indexPatterns['1'], + fields: [ + { + name: 'timestamp', + displayName: 'timestamp', + aggregatable: true, + searchable: true, + type: 'date', + aggregationRestrictions: { + date_histogram: { + agg: 'date_histogram', + time_zone: 'UTC', + calendar_interval: '42w', + }, + }, + }, + ], + } + ); + expect(esAggsConfig).toEqual( + expect.objectContaining({ + params: expect.objectContaining({ + interval: '42w', + field: 'timestamp', + useNormalizedEsInterval: false, }), }) ); @@ -300,6 +339,7 @@ describe('date_histogram', () => { { title: '', id: '', + hasRestrictions: true, fields: [ { name: 'dateField', @@ -343,6 +383,7 @@ describe('date_histogram', () => { { title: '', id: '', + hasRestrictions: false, fields: [ { name: 'dateField', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx index 2236bc576e2b6..57454291d43c5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx @@ -119,21 +119,24 @@ export const dateHistogramOperation: OperationDefinition ({ - id: columnId, - enabled: true, - type: 'date_histogram', - schema: 'segment', - params: { - field: column.sourceField, - time_zone: column.params.timeZone, - useNormalizedEsInterval: true, - interval: column.params.interval, - drop_partials: false, - min_doc_count: 0, - extended_bounds: {}, - }, - }), + toEsAggsConfig: (column, columnId, indexPattern) => { + const usedField = indexPattern.fields.find((field) => field.name === column.sourceField); + return { + id: columnId, + enabled: true, + type: 'date_histogram', + schema: 'segment', + params: { + field: column.sourceField, + time_zone: column.params.timeZone, + useNormalizedEsInterval: !usedField || !usedField.aggregationRestrictions?.date_histogram, + interval: column.params.interval, + drop_partials: false, + min_doc_count: 0, + extended_bounds: {}, + }, + }; + }, paramEditor: ({ state, setState, currentColumn: currentColumn, layerId, dateRange, data }) => { const field = currentColumn && diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts index ef12fca690f0c..8ef53c1e0b425 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts @@ -84,7 +84,7 @@ interface BaseOperationDefinitionProps { * Function turning a column into an agg config passed to the `esaggs` function * together with the agg configs returned from other columns. */ - toEsAggsConfig: (column: C, columnId: string) => unknown; + toEsAggsConfig: (column: C, columnId: string, indexPattern: IndexPattern) => unknown; /** * Returns true if the `column` can also be used on `newIndexPattern`. * If this function returns false, the column is removed when switching index pattern diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx index e6c8a5f6ac852..4c37d95f6b050 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx @@ -68,7 +68,7 @@ function buildMetricOperation>({ sourceField: field.name, }; }, - toEsAggsConfig: (column, columnId) => ({ + toEsAggsConfig: (column, columnId, _indexPattern) => ({ id: columnId, enabled: true, type: column.operationType, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx index 05bb2ef673888..2972ed2d0231b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx @@ -13,7 +13,7 @@ import { dataPluginMock } from '../../../../../../../src/plugins/data/public/moc import { createMockedIndexPattern } from '../../mocks'; import { TermsIndexPatternColumn } from './terms'; import { termsOperation } from './index'; -import { IndexPatternPrivateState } from '../../types'; +import { IndexPatternPrivateState, IndexPattern } from '../../types'; const defaultProps = { storage: {} as IStorageWrapper, @@ -69,7 +69,8 @@ describe('terms', () => { it('should reflect params correctly', () => { const esAggsConfig = termsOperation.toEsAggsConfig( state.layers.first.columns.col1 as TermsIndexPatternColumn, - 'col1' + 'col1', + {} as IndexPattern ); expect(esAggsConfig).toEqual( expect.objectContaining({ diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx index ac1ff9da2fea0..c1b19fd5549e7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx @@ -95,7 +95,7 @@ export const termsOperation: OperationDefinition = { }, }; }, - toEsAggsConfig: (column, columnId) => ({ + toEsAggsConfig: (column, columnId, _indexPattern) => ({ id: columnId, enabled: true, type: 'terms', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts index 3fce2562f528e..4ac3fc89500f9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts @@ -16,6 +16,7 @@ const expectedIndexPatterns = { id: '1', title: 'my-fake-index-pattern', timeFieldName: 'timestamp', + hasRestrictions: false, fields: [ { name: 'timestamp', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts index d7fd0d3661c86..7b6eb11efc494 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts @@ -570,6 +570,7 @@ describe('state_helpers', () => { const indexPattern: IndexPattern = { id: 'test', title: '', + hasRestrictions: true, fields: [ { name: 'fieldA', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts index 9473a1523b8ca..1b87c48dc7193 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts @@ -21,7 +21,11 @@ function getExpressionForLayer( } function getEsAggsConfig(column: C, columnId: string) { - return operationDefinitionMap[column.operationType].toEsAggsConfig(column, columnId); + return operationDefinitionMap[column.operationType].toEsAggsConfig( + column, + columnId, + indexPattern + ); } const columnEntries = columnOrder.map((colId) => [colId, columns[colId]] as const); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts index 95cc47e68f8a1..c101f1354b703 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts @@ -19,6 +19,7 @@ export interface IndexPattern { params: unknown; } >; + hasRestrictions: boolean; } export interface IndexPatternField { diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts index ad4479d3a324b..fa614ae87b290 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.d.ts @@ -32,7 +32,6 @@ export interface IVectorLayer extends ILayer { getJoins(): IJoin[]; getValidJoins(): IJoin[]; getSource(): IVectorSource; - getStyle(): IVectorStyle; getFeatureById(id: string | number): Feature | null; getPropertiesForTooltip(properties: GeoJsonProperties): Promise; hasJoins(): boolean; @@ -79,7 +78,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { _setMbPointsProperties(mbMap: unknown, mvtSourceLayer?: string): void; _setMbLinePolygonProperties(mbMap: unknown, mvtSourceLayer?: string): void; getSource(): IVectorSource; - getStyle(): IVectorStyle; getFeatureById(id: string | number): Feature | null; getPropertiesForTooltip(properties: GeoJsonProperties): Promise; hasJoins(): boolean; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts b/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts index 3f6edc81e30ef..a2dfdc94d8058 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts @@ -5,7 +5,7 @@ */ // eslint-disable-next-line max-classes-per-file -import { FIELD_ORIGIN } from '../../../../../../common/constants'; +import { FIELD_ORIGIN, LAYER_STYLE_TYPE } from '../../../../../../common/constants'; import { StyleMeta } from '../../style_meta'; import { CategoryFieldMeta, @@ -44,7 +44,7 @@ export class MockStyle implements IStyle { } getType() { - return 'mockStyle'; + return LAYER_STYLE_TYPE.VECTOR; } getStyleMeta(): StyleMeta { diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx index 47659e055936e..826acd41e27a9 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.tsx @@ -27,6 +27,7 @@ import { import { IField } from '../../../fields/field'; import { IVectorLayer } from '../../../layers/vector_layer/vector_layer'; import { IJoin } from '../../../joins/join'; +import { IVectorStyle } from '../vector_style'; export interface IDynamicStyleProperty extends IStyleProperty { getFieldMetaOptions(): FieldMetaOptions; @@ -88,7 +89,7 @@ export class DynamicStyleProperty extends AbstractStyleProperty } getRangeFieldMeta() { - const style = this._layer.getStyle(); + const style = this._layer.getStyle() as IVectorStyle; const styleMeta = style.getStyleMeta(); const fieldName = this.getFieldName(); const rangeFieldMetaFromLocalFeatures = styleMeta.getRangeFieldMetaDescriptor(fieldName); @@ -113,7 +114,7 @@ export class DynamicStyleProperty extends AbstractStyleProperty } getCategoryFieldMeta() { - const style = this._layer.getStyle(); + const style = this._layer.getStyle() as IVectorStyle; const styleMeta = style.getStyleMeta(); const fieldName = this.getFieldName(); const categoryFieldMetaFromLocalFeatures = styleMeta.getCategoryFieldMetaDescriptor(fieldName); diff --git a/x-pack/plugins/maps/public/components/tooltip_selector/tooltip_selector.tsx b/x-pack/plugins/maps/public/components/tooltip_selector/tooltip_selector.tsx index 84316a1b9105d..9bab590d1f5ea 100644 --- a/x-pack/plugins/maps/public/components/tooltip_selector/tooltip_selector.tsx +++ b/x-pack/plugins/maps/public/components/tooltip_selector/tooltip_selector.tsx @@ -13,8 +13,10 @@ import { EuiDroppable, EuiText, EuiTextAlign, + EuiTextColor, EuiSpacer, } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { AddTooltipFieldPopover, FieldProps } from './add_tooltip_field_popover'; import { IField } from '../../classes/fields/field'; @@ -156,7 +158,18 @@ export class TooltipSelector extends Component { _renderProperties() { if (!this.state.selectedFieldProps.length) { - return null; + return ( + +

+ + + +

+
+ ); } return ( diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.test.tsx b/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.test.tsx new file mode 100644 index 0000000000000..e8e0e583a7c6d --- /dev/null +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.test.tsx @@ -0,0 +1,36 @@ +/* + * 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 { getBreadcrumbs } from './get_breadcrumbs'; + +jest.mock('../../../kibana_services', () => {}); +jest.mock('../../maps_router', () => {}); + +const getHasUnsavedChanges = () => { + return false; +}; + +test('should get breadcrumbs "Maps / mymap"', () => { + const breadcrumbs = getBreadcrumbs({ title: 'mymap', getHasUnsavedChanges }); + expect(breadcrumbs.length).toBe(2); + expect(breadcrumbs[0].text).toBe('Maps'); + expect(breadcrumbs[1].text).toBe('mymap'); +}); + +test('should get breadcrumbs "Dashboard / Maps / mymap" with originatingApp', () => { + const breadcrumbs = getBreadcrumbs({ + title: 'mymap', + getHasUnsavedChanges, + originatingApp: 'dashboardId', + getAppNameFromId: (appId) => { + return 'Dashboard'; + }, + }); + expect(breadcrumbs.length).toBe(3); + expect(breadcrumbs[0].text).toBe('Dashboard'); + expect(breadcrumbs[1].text).toBe('Maps'); + expect(breadcrumbs[2].text).toBe('mymap'); +}); diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx b/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx new file mode 100644 index 0000000000000..1ccf890597edc --- /dev/null +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/get_breadcrumbs.tsx @@ -0,0 +1,59 @@ +/* + * 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 { getNavigateToApp } from '../../../kibana_services'; +// @ts-expect-error +import { goToSpecifiedPath } from '../../maps_router'; + +export const unsavedChangesWarning = i18n.translate( + 'xpack.maps.breadCrumbs.unsavedChangesWarning', + { + defaultMessage: 'Your map has unsaved changes. Are you sure you want to leave?', + } +); + +export function getBreadcrumbs({ + title, + getHasUnsavedChanges, + originatingApp, + getAppNameFromId, +}: { + title: string; + getHasUnsavedChanges: () => boolean; + originatingApp?: string; + getAppNameFromId?: (id: string) => string; +}) { + const breadcrumbs = []; + if (originatingApp && getAppNameFromId) { + breadcrumbs.push({ + onClick: () => { + getNavigateToApp()(originatingApp); + }, + text: getAppNameFromId(originatingApp), + }); + } + + breadcrumbs.push({ + text: i18n.translate('xpack.maps.mapController.mapsBreadcrumbLabel', { + defaultMessage: 'Maps', + }), + onClick: () => { + if (getHasUnsavedChanges()) { + const navigateAway = window.confirm(unsavedChangesWarning); + if (navigateAway) { + goToSpecifiedPath('/'); + } + } else { + goToSpecifiedPath('/'); + } + }, + }); + + breadcrumbs.push({ text: title }); + + return breadcrumbs; +} diff --git a/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js b/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js index 58f0bf16e93f2..485b0ed7682fa 100644 --- a/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js +++ b/x-pack/plugins/maps/public/routing/routes/maps_app/maps_app_view.js @@ -5,7 +5,6 @@ */ import React from 'react'; -import { i18n } from '@kbn/i18n'; import 'mapbox-gl/dist/mapbox-gl.css'; import _ from 'lodash'; import { DEFAULT_IS_LAYER_TOC_OPEN } from '../../../reducers/ui'; @@ -29,13 +28,9 @@ import { AppStateManager } from '../../state_syncing/app_state_manager'; import { startAppStateSyncing } from '../../state_syncing/app_sync'; import { esFilters } from '../../../../../../../src/plugins/data/public'; import { MapContainer } from '../../../connected_components/map_container'; -import { goToSpecifiedPath } from '../../maps_router'; import { getIndexPatternsFromIds } from '../../../index_pattern_util'; import { getTopNavConfig } from './top_nav_config'; - -const unsavedChangesWarning = i18n.translate('xpack.maps.breadCrumbs.unsavedChangesWarning', { - defaultMessage: 'Your map has unsaved changes. Are you sure you want to leave?', -}); +import { getBreadcrumbs, unsavedChangesWarning } from './get_breadcrumbs'; export class MapsAppView extends React.Component { _globalSyncUnsubscribe = null; @@ -104,7 +99,7 @@ export class MapsAppView extends React.Component { getCoreChrome().setBreadcrumbs([]); } - _hasUnsavedChanges() { + _hasUnsavedChanges = () => { const savedLayerList = this.props.savedMap.getLayerList(); return !savedLayerList ? !_.isEqual(this.props.layerListConfigOnly, this.state.initialLayerListConfig) @@ -114,27 +109,16 @@ export class MapsAppView extends React.Component { // Need to perform the same process for layerListConfigOnly to compare apples to apples // and avoid undefined properties in layerListConfigOnly triggering unsaved changes. !_.isEqual(JSON.parse(JSON.stringify(this.props.layerListConfigOnly)), savedLayerList); - } + }; _setBreadcrumbs = () => { - getCoreChrome().setBreadcrumbs([ - { - text: i18n.translate('xpack.maps.mapController.mapsBreadcrumbLabel', { - defaultMessage: 'Maps', - }), - onClick: () => { - if (this._hasUnsavedChanges()) { - const navigateAway = window.confirm(unsavedChangesWarning); - if (navigateAway) { - goToSpecifiedPath('/'); - } - } else { - goToSpecifiedPath('/'); - } - }, - }, - { text: this.props.savedMap.title }, - ]); + const breadcrumbs = getBreadcrumbs({ + title: this.props.savedMap.title, + getHasUnsavedChanges: this._hasUnsavedChanges, + originatingApp: this.state.originatingApp, + getAppNameFromId: this.props.stateTransfer.getAppNameFromId, + }); + getCoreChrome().setBreadcrumbs(breadcrumbs); }; _updateFromGlobalState = ({ changes, state: globalState }) => { diff --git a/x-pack/plugins/security_solution/public/common/store/epic.ts b/x-pack/plugins/security_solution/public/common/store/epic.ts index d9de7951a86f4..51a9377b9fd04 100644 --- a/x-pack/plugins/security_solution/public/common/store/epic.ts +++ b/x-pack/plugins/security_solution/public/common/store/epic.ts @@ -4,14 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import { combineEpics } from 'redux-observable'; +import { combineEpics, Epic } from 'redux-observable'; +import { Action } from 'redux'; + import { createTimelineEpic } from '../../timelines/store/timeline/epic'; import { createTimelineFavoriteEpic } from '../../timelines/store/timeline/epic_favorite'; import { createTimelineNoteEpic } from '../../timelines/store/timeline/epic_note'; import { createTimelinePinnedEventEpic } from '../../timelines/store/timeline/epic_pinned_event'; import { createTimelineLocalStorageEpic } from '../../timelines/store/timeline/epic_local_storage'; +import { TimelineEpicDependencies } from '../../timelines/store/timeline/types'; -export const createRootEpic = () => +export const createRootEpic = (): Epic< + Action, + Action, + State, + TimelineEpicDependencies +> => combineEpics( createTimelineEpic(), createTimelineFavoriteEpic(), diff --git a/x-pack/plugins/security_solution/public/common/store/store.ts b/x-pack/plugins/security_solution/public/common/store/store.ts index a39c9f18bcdb8..f041e1fd82a9f 100644 --- a/x-pack/plugins/security_solution/public/common/store/store.ts +++ b/x-pack/plugins/security_solution/public/common/store/store.ts @@ -13,6 +13,7 @@ import { Middleware, Dispatch, PreloadedState, + CombinedState, } from 'redux'; import { createEpicMiddleware } from 'redux-observable'; @@ -30,6 +31,7 @@ import { Immutable } from '../../../common/endpoint/types'; import { State } from './types'; import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; import { CoreStart } from '../../../../../../src/core/public'; +import { TimelineEpicDependencies } from '../../timelines/store/timeline/types'; type ComposeType = typeof compose; declare global { @@ -56,7 +58,7 @@ export const createStore = ( ): Store => { const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; - const middlewareDependencies = { + const middlewareDependencies: TimelineEpicDependencies = { apolloClient$: apolloClient, kibana$: kibana, selectAllTimelineQuery: inputsSelectors.globalQueryByIdSelector, @@ -80,7 +82,7 @@ export const createStore = ( ) ); - epicMiddleware.run(createRootEpic()); + epicMiddleware.run(createRootEpic>()); return store; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx index 5bab2e3c78970..ca17d331c67e5 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/default_config.tsx @@ -9,6 +9,8 @@ import ApolloClient from 'apollo-client'; import { Dispatch } from 'redux'; import { EuiText } from '@elastic/eui'; +import { RuleType } from '../../../../common/detection_engine/types'; +import { isMlRule } from '../../../../common/machine_learning/helpers'; import { RowRendererId } from '../../../../common/types/timeline'; import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants'; import { Status } from '../../../../common/detection_engine/schemas/common/schemas'; @@ -39,6 +41,7 @@ import { import { Ecs, TimelineNonEcsData } from '../../../graphql/types'; import { AddExceptionModalBaseProps } from '../../../common/components/exceptions/add_exception_modal'; import { getMappedNonEcsValue } from '../../../common/components/exceptions/helpers'; +import { isThresholdRule } from '../../../../common/detection_engine/utils'; export const buildAlertStatusFilter = (status: Status): Filter[] => [ { @@ -193,6 +196,7 @@ export const requiredFieldsForActions = [ 'signal.rule.query', 'signal.rule.to', 'signal.rule.id', + 'signal.rule.type', 'signal.original_event.kind', 'signal.original_event.module', @@ -317,6 +321,15 @@ export const getAlertActions = ({ return module === 'endpoint' && kind === 'alert'; }; + const exceptionsAreAllowed = () => { + const ruleTypes = getMappedNonEcsValue({ + data: nonEcsRowData, + fieldName: 'signal.rule.type', + }); + const [ruleType] = ruleTypes as RuleType[]; + return !isMlRule(ruleType) && !isThresholdRule(ruleType); + }; + return [ { ...getInvestigateInResolverAction({ dispatch, timelineId }), @@ -386,7 +399,7 @@ export const getAlertActions = ({ } }, id: 'addException', - isActionDisabled: () => !canUserCRUD || !hasIndexWrite, + isActionDisabled: () => !canUserCRUD || !hasIndexWrite || !exceptionsAreAllowed(), dataTestSubj: 'add-exception-menu-item', ariaLabel: 'Add Exception', content: {i18n.ACTION_ADD_EXCEPTION}, diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index f1a933fb34d66..a691dd98e7081 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -66,7 +66,7 @@ export class Plugin implements IPlugin, plugins: SetupPlugins) { + public setup(core: CoreSetup, plugins: SetupPlugins): PluginSetup { initTelemetry(plugins.usageCollection, APP_ID); plugins.home.featureCatalogue.register({ @@ -319,7 +319,12 @@ export class Plugin implements IPlugin { + const { resolverPluginSetup } = await import('./resolver'); + return resolverPluginSetup(); + }, + }; } public start(core: CoreStart, plugins: StartPlugins) { diff --git a/x-pack/plugins/security_solution/public/resolver/index.ts b/x-pack/plugins/security_solution/public/resolver/index.ts new file mode 100644 index 0000000000000..409f82c9d1560 --- /dev/null +++ b/x-pack/plugins/security_solution/public/resolver/index.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 { Provider } from 'react-redux'; +import { ResolverPluginSetup } from './types'; +import { resolverStoreFactory } from './store/index'; +import { ResolverWithoutProviders } from './view/resolver_without_providers'; +import { noAncestorsTwoChildren } from './data_access_layer/mocks/no_ancestors_two_children'; + +/** + * These exports are used by the plugin 'resolverTest' defined in x-pack's plugin_functional suite. + */ + +/** + * Provide access to Resolver APIs. + */ +export function resolverPluginSetup(): ResolverPluginSetup { + return { + Provider, + storeFactory: resolverStoreFactory, + ResolverWithoutProviders, + mocks: { + dataAccessLayer: { + noAncestorsTwoChildren, + }, + }, + }; +} diff --git a/x-pack/plugins/security_solution/public/resolver/store/index.ts b/x-pack/plugins/security_solution/public/resolver/store/index.ts index 950a61db33f17..ed8a5129c7ff6 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/index.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/index.ts @@ -11,7 +11,7 @@ import { resolverReducer } from './reducer'; import { resolverMiddlewareFactory } from './middleware'; import { ResolverAction } from './actions'; -export const storeFactory = ( +export const resolverStoreFactory = ( dataAccessLayer: DataAccessLayer ): Store => { const actionsDenylist: Array = ['userMovedPointer']; diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index b79b7df48a6de..a6520c8f0e06f 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { Store, createStore, applyMiddleware } from 'redux'; import { mount, ReactWrapper } from 'enzyme'; -import { createMemoryHistory, History as HistoryPackageHistoryInterface } from 'history'; +import { History as HistoryPackageHistoryInterface, createMemoryHistory } from 'history'; import { CoreStart } from '../../../../../../../src/core/public'; import { coreMock } from '../../../../../../../src/core/public/mocks'; import { spyMiddlewareFactory } from '../spy_middleware_factory'; diff --git a/x-pack/plugins/security_solution/public/resolver/types.ts b/x-pack/plugins/security_solution/public/resolver/types.ts index 97d97700b11ae..33f7a1d97db13 100644 --- a/x-pack/plugins/security_solution/public/resolver/types.ts +++ b/x-pack/plugins/security_solution/public/resolver/types.ts @@ -9,6 +9,7 @@ import { Store } from 'redux'; import { Middleware, Dispatch } from 'redux'; import { BBox } from 'rbush'; +import { Provider } from 'react-redux'; import { ResolverAction } from './store/actions'; import { ResolverRelatedEvents, @@ -410,7 +411,7 @@ export interface SideEffectSimulator { /** * Mocked `SideEffectors`. */ - mock: jest.Mocked> & Pick; + mock: SideEffectors; } /** @@ -532,3 +533,42 @@ export interface SpyMiddleware { */ debugActions: () => () => void; } + +/** + * values of this type are exposed by the Security Solution plugin's setup phase. + */ +export interface ResolverPluginSetup { + /** + * Provide access to the instance of the `react-redux` `Provider` that Resolver recognizes. + */ + Provider: typeof Provider; + /** + * Takes a `DataAccessLayer`, which could be a mock one, and returns an redux Store. + * All data acess (e.g. HTTP requests) are done through the store. + */ + storeFactory: (dataAccessLayer: DataAccessLayer) => Store; + + /** + * The Resolver component without the required Providers. + * You must wrap this component in: `I18nProvider`, `Router` (from react-router,) `KibanaContextProvider`, + * and the `Provider` component provided by this object. + */ + ResolverWithoutProviders: React.MemoExoticComponent< + React.ForwardRefExoticComponent> + >; + + /** + * A collection of mock objects that can be used in examples or in testing. + */ + mocks: { + /** + * Mock `DataAccessLayer`s. All of Resolver's HTTP access is provided by a `DataAccessLayer`. + */ + dataAccessLayer: { + /** + * A mock `DataAccessLayer` that returns a tree that has no ancestor nodes but which has 2 children nodes. + */ + noAncestorsTwoChildren: () => { dataAccessLayer: DataAccessLayer }; + }; + }; +} diff --git a/x-pack/plugins/security_solution/public/resolver/view/index.tsx b/x-pack/plugins/security_solution/public/resolver/view/index.tsx index d9a0bf291d0e4..bcc420435e5d9 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/index.tsx @@ -7,7 +7,7 @@ import React, { useMemo } from 'react'; import { Provider } from 'react-redux'; -import { storeFactory } from '../store'; +import { resolverStoreFactory } from '../store'; import { StartServices } from '../../types'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; import { DataAccessLayer, ResolverProps } from '../types'; @@ -24,7 +24,7 @@ export const Resolver = React.memo((props: ResolverProps) => { ]); const store = useMemo(() => { - return storeFactory(dataAccessLayer); + return resolverStoreFactory(dataAccessLayer); }, [dataAccessLayer]); return ( diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/types.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/types.ts index c64ed608339b6..8a5344e0754db 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/types.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/types.ts @@ -10,9 +10,9 @@ import { Storage } from '../../../../../../../src/plugins/kibana_utils/public'; import { AppApolloClient } from '../../../common/lib/lib'; import { inputsModel } from '../../../common/store/inputs'; import { NotesById } from '../../../common/store/app/model'; -import { StartServices } from '../../../types'; import { TimelineModel } from './model'; +import { CoreStart } from '../../../../../../../src/core/public'; export interface AutoSavedWarningMsg { timelineId: string | null; @@ -55,6 +55,6 @@ export interface TimelineEpicDependencies { selectAllTimelineQuery: () => (state: State, id: string) => inputsModel.GlobalQuery; selectNotesByIdSelector: (state: State) => NotesById; apolloClient$: Observable; - kibana$: Observable; + kibana$: Observable; storage: Storage; } diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index 3913b96b3e11a..fd1ff566a7719 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -21,6 +21,7 @@ import { } from '../../triggers_actions_ui/public'; import { SecurityPluginSetup } from '../../security/public'; import { AppFrontendLibs } from './common/lib/lib'; +import { ResolverPluginSetup } from './resolver/types'; export interface SetupPlugins { home: HomePublicPluginSetup; @@ -46,8 +47,9 @@ export type StartServices = CoreStart & storage: Storage; }; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface PluginSetup {} +export interface PluginSetup { + resolver: () => Promise; +} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface PluginStart {} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json index 25274928aa2b7..a8be0fe97524e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies certutil.exe making a network connection. Adversaries could abuse certutil.exe to download a certificate, or malware, from a remote URL.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json index 6be1f037f967e..f2032b5bef218 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json @@ -6,6 +6,7 @@ "false_positives": [ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_tcpdump_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_tcpdump_activity.json index d5b069f7b81e7..306a38f5d2a28 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_tcpdump_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_tcpdump_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Some normal use of this command may originate from server or network administrators engaged in network troubleshooting." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json index b22b74ebc53bc..c80f24a21d958 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Adversaries can add the 'hidden' attribute to files to hide them from the user in an attempt to evade detection.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -51,5 +52,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_iptables_or_firewall.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_iptables_or_firewall.json index e2ba81da917b3..4d4f10bbaa599 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_iptables_or_firewall.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_iptables_or_firewall.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Adversaries may attempt to disable the iptables or firewall service in an attempt to affect how a host is allowed to receive or send network traffic.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json index 4f4a9aacd79aa..3c34b04a77a50 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Adversaries may attempt to disable the syslog service in an attempt to an attempt to disrupt event logging and evade detection by security controls.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.json index 5bcc4a00ccd82..3cdfac92572b1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Automated tools such as Jenkins may encode or decode files as part of their normal behavior. These events can be filtered by the process executable or username values." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base64_encoding_or_decoding_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base64_encoding_or_decoding_activity.json index a17fd6d2702dd..2d26d867b8718 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base64_encoding_or_decoding_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base64_encoding_or_decoding_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Automated tools such as Jenkins may encode or decode files as part of their normal behavior. These events can be filtered by the process executable or username values." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json index cf09bc512916f..60ce575148f4c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies attempts to clear Windows event log stores. This is often done by attackers in an attempt to evade detection or destroy forensic evidence on a system.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json index 0c82444dd9397..50213b9f1a42c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies use of the fsutil.exe to delete the volume USNJRNL. This technique is used by attackers to eliminate evidence of files created during post-exploitation activities.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json index c76c5f20fa88b..026735f413eab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_backup_catalogs_with_wbadmin.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies use of the wbadmin.exe to delete the backup catalog. Ransomware and other malware may do this to prevent system recovery.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json index b38ed94e132e1..85d8bdcb2582f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Adversaries may attempt to clear the bash command line history in an attempt to evade detection or forensic investigations.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json index 229a03de39600..d107c0b262091 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies potential attempts to disable Security-Enhanced Linux (SELinux), which is a Linux kernel security feature to support access control policies. Adversaries may disable security tools to avoid possible detection of their tools and activities.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json index 4800e87c180e2..6fbf9ca800f79 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies use of the netsh.exe to disable or weaken the local firewall. Attackers will use this command line tool to disable the firewall during troubleshooting or to enable network mobility.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_encoding_or_decoding_files_via_certutil.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_encoding_or_decoding_files_via_certutil.json index 075dd13d9819b..0d47aab2c64bd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_encoding_or_decoding_files_via_certutil.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_encoding_or_decoding_files_via_certutil.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies the use of certutil.exe to encode or decode data. CertUtil is a native Windows component which is part of Certificate Services. CertUtil is often abused by attackers to encode or decode base64 data for stealthier command and control or exfiltration.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json index 133863f8e2148..df7fc85b63d4a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json @@ -6,6 +6,7 @@ "false_positives": [ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual. It is quite unusual for this program to be started by an Office application like Word or Excel." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -57,5 +58,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json index 85d348bb14be0..aa4674f75bcd0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json @@ -6,6 +6,7 @@ "false_positives": [ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json index 38482c0a70fc9..da7d91933bd2a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json @@ -6,6 +6,7 @@ "false_positives": [ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json index 7db683caf2bb2..8e4f7366a7657 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json @@ -6,6 +6,7 @@ "false_positives": [ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json index 1c4666955dde0..4f353a6ff9e6f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json @@ -6,6 +6,7 @@ "false_positives": [ "The Build Engine is commonly used by Windows developers but use by non-engineers is unusual. If a build system triggers this rule it can be exempted by process, user or host name." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -42,5 +43,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json index c375ea7b19b37..5b02f63a1c7f7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Malware or other files dropped or created on a system by an adversary may leave traces behind as to what was done within a network and how. Adversaries may remove these files over the course of an intrusion to keep their footprint low or remove them at the end as part of the post-intrusion cleanup process.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_mod_writable_dir.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_mod_writable_dir.json index 22090e1a241e7..8ee2d4fda7bf8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_mod_writable_dir.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_mod_writable_dir.json @@ -6,6 +6,7 @@ "false_positives": [ "Certain programs or applications may modify files or change ownership in writable directories. These can be exempted by username." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hex_encoding_or_decoding_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hex_encoding_or_decoding_activity.json index 00491937e9aae..f5345b2276e8a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hex_encoding_or_decoding_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hex_encoding_or_decoding_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Automated tools such as Jenkins may encode or decode files as part of their normal behavior. These events can be filtered by the process executable or username values." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json index 16a398011fc53..e66968a50709e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json @@ -6,6 +6,7 @@ "false_positives": [ "Certain tools may create hidden temporary files or directories upon installation or as part of their normal behavior. These events can be filtered by the process arguments, username, or process name values." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -55,5 +56,5 @@ } ], "type": "query", - "version": 1 + "version": 2 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json index 11781cb719599..ad751a1031437 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json @@ -6,6 +6,7 @@ "false_positives": [ "There is usually no reason to remove modules, but some buggy modules require it. These can be exempted by username. Note that some Linux distributions are not built to support the removal of modules at all." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -57,5 +58,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json index 7d931725fa6eb..5b5f69a0aef74 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Binaries signed with trusted digital certificates can execute on Windows systems protected by digital signature validation. Adversaries may use these binaries to 'live off the land' and execute malicious files that could bypass application allowlists and signature validation.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -51,5 +52,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json index 1bffe7a1cfc24..6025fc5ca6452 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modification_of_boot_config.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies use of bcdedit.exe to delete boot configuration data. This tactic is sometimes used as by malware or an attacker as a destructive technique.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json index f3cc5c2eec8a3..8a504281b03f7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_vssadmin.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies use of vssadmin.exe for shadow copy deletion on endpoints. This commonly occurs in tandem with ransomware or other destructive attacks.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json index 334276142ca42..2ae938bb34104 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_volume_shadow_copy_deletion_via_wmic.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies use of wmic.exe for shadow copy deletion on endpoints. This commonly occurs in tandem with ransomware or other destructive attacks.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_kernel_module_enumeration.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_kernel_module_enumeration.json index 0e4bea426c591..af9c4b5409964 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_kernel_module_enumeration.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_kernel_module_enumeration.json @@ -6,6 +6,7 @@ "false_positives": [ "Security tools and device drivers may run these programs in order to enumerate kernel modules. Use of these programs by ordinary users is uncommon. These can be exempted by process name or username." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json index 6ac2bbf355961..f1a214b7cd436 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_command_system_account.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies the SYSTEM account using the Net utility. The Net utility is a component of the Windows operating system. It is used in command line operations for control of users, groups, services, and network connections.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting.json index e73aa5f4566a7..d913a92e2ee0e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting.json @@ -6,6 +6,7 @@ "false_positives": [ "Certain tools or automated software may enumerate hardware information. These tools can be exempted via user name or process arguments to eliminate potential noise." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_commmand.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_commmand.json index 0017186787139..a8b34362d9579 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_commmand.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_commmand.json @@ -6,6 +6,7 @@ "false_positives": [ "Security testing tools and frameworks may run this command. Some normal use of this command may originate from automation tools and frameworks." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_prompt_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_prompt_connecting_to_the_internet.json index 0ba6480fe42a1..46208f3753fa1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_prompt_connecting_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_prompt_connecting_to_the_internet.json @@ -6,6 +6,7 @@ "false_positives": [ "Administrators may use the command prompt for regular administrative tasks. It's important to baseline your environment for network connections being made from the command prompt to determine any abnormal use of this tool." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json index 2d3edb0f5f6cc..c619d8f764bc4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_powershell.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies a suspicious parent child process relationship with cmd.exe descending from PowerShell.exe.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -51,5 +52,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json index 3a4b4915f3c8b..140212e4148eb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies a suspicious parent child process relationship with cmd.exe descending from svchost.exe", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json index a2eb76b9831f0..963c6b2e53ed6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Compiled HTML files (.chm) are commonly distributed as part of the Microsoft HTML Help system. Adversaries may conceal malicious code in a CHM file and deliver it to a victim for execution. CHM content is loaded by the HTML Help executable program (hh.exe).", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -51,5 +52,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_local_service_commands.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_local_service_commands.json index e43ab9de86ef7..7b20cefdc67f0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_local_service_commands.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_local_service_commands.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies use of sc.exe to create, modify, or start services on remote hosts. This could be indicative of adversary lateral movement but will be noisy if commonly done by admins.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msbuild_making_network_connections.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msbuild_making_network_connections.json index 9d480259d49de..629efa90a71ea 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msbuild_making_network_connections.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msbuild_making_network_connections.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies MsBuild.exe making outbound network connections. This may indicate adversarial activity as MsBuild is often leveraged by adversaries to execute code and evade detection.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_mshta_making_network_connections.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_mshta_making_network_connections.json index cdef5f16e5cd7..7af823070889f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_mshta_making_network_connections.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_mshta_making_network_connections.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies mshta.exe making a network connection. This may indicate adversarial activity as mshta.exe is often leveraged by adversaries to execute malicious scripts and evade detection.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msxsl_network.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msxsl_network.json index d501bda08c3a5..1dc75575636fb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msxsl_network.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_msxsl_network.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies msxsl.exe making a network connection. This may indicate adversarial activity as msxsl.exe is often leveraged by adversaries to execute malicious scripts and evade detection.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_perl_tty_shell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_perl_tty_shell.json index e82b42869e44d..9b6ee099116f3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_perl_tty_shell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_perl_tty_shell.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies when a terminal (tty) is spawned via Perl. Attackers may upgrade a simple reverse shell to a fully interactive tty after obtaining initial access to a host.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json index e4c84fd3c3b83..f647d8d00e084 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json @@ -6,6 +6,7 @@ "false_positives": [ "PsExec is a dual-use tool that can be used for benign or malicious activity. It's important to baseline your environment to determine the amount of noise to expect from this tool." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_python_tty_shell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_python_tty_shell.json index 3aa9ac20bba9e..d9c26a9c26cc9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_python_tty_shell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_python_tty_shell.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies when a terminal (tty) is spawned via Python. Attackers may upgrade a simple reverse shell to a fully interactive tty after obtaining initial access to a host.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json index 0a1ba97bd01ea..b3b6a2b0c7fab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json @@ -6,6 +6,7 @@ "false_positives": [ "Security testing may produce events like this. Activity of this kind performed by non-engineers and ordinary users is unusual." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -54,5 +55,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_executing_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_executing_powershell.json index 7305247192f57..6d7f11f01fae0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_executing_powershell.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_executing_powershell.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies a PowerShell process launched by either cscript.exe or wscript.exe. Observing Windows scripting processes executing a PowerShell script, may be indicative of malicious activity.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_office_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_office_child_process.json index 7ff8eb9424d5f..005a0c38c8a8b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_office_child_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_office_child_process.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies suspicious child processes of frequently targeted Microsoft Office applications (Word, PowerPoint, Excel). These child processes are often launched during exploitation of Office applications or from documents with malicious macros.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_outlook_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_outlook_child_process.json index e923407765f8f..74e21c7d17479 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_outlook_child_process.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_ms_outlook_child_process.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies suspicious child processes of Microsoft Outlook. These child processes are often associated with spear phishing activity.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json index 24a744ce30832..adf1a76bfb901 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies suspicious child processes of PDF reader applications. These child processes are often launched via exploitation of PDF applications or social engineering.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_network_connection_via_rundll32.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_network_connection_via_rundll32.json index 529f2199e46dc..1104159350655 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_network_connection_via_rundll32.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_network_connection_via_rundll32.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies unusual instances of rundll32.exe making outbound network connections. This may indicate adversarial activity and may identify malicious DLLs.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_process_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_process_network_connection.json index 69a25b3b24bac..854ecc40d76ab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_process_network_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_unusual_process_network_connection.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies network activity from unexpected system applications. This may indicate adversarial activity as these applications are often leveraged by adversaries to execute code and evade detection.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json index cae5d1b7e0f1f..d9dcbfe25a4c2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_net_com_assemblies.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "RegSvcs.exe and RegAsm.exe are Windows command line utilities that are used to register .NET Component Object Model (COM) assemblies. Adversaries can use RegSvcs.exe and RegAsm.exe to proxy execution of code through a trusted Windows utility.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -51,5 +52,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json index 8a68b26abad20..e4014b22a6c09 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies unexpected processes making network connections over port 445. Windows File Sharing is typically implemented over Server Message Block (SMB), which communicates between hosts using port 445. When legitimate, these network connections are established by the kernel. Processes making 445/tcp connections may be port scanners, exploits, or suspicious user-level processes moving laterally.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_external.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_external.json index 2ea75dbd758cb..e4804329c0f30 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_external.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_external.json @@ -6,6 +6,7 @@ "false_positives": [ "Telnet can be used for both benign or malicious purposes. Telnet is included by default in some Linux distributions, so its presence is not inherently suspicious. The use of Telnet to manage devices remotely has declined in recent years in favor of more secure protocols such as SSH. Telnet usage by non-automated tools or frameworks may be suspicious." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_internal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_internal.json index 4379759608aba..30312987d166c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_internal.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_internal.json @@ -6,6 +6,7 @@ "false_positives": [ "Telnet can be used for both benign or malicious purposes. Telnet is included by default in some Linux distributions, so its presence is not inherently suspicious. The use of Telnet to manage devices remotely has declined in recent years in favor of more secure protocols such as SSH. Telnet usage by non-automated tools or frameworks may be suspicious." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_hping_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_hping_activity.json index 24104439cd0ec..3a5c4d9e69d49 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_hping_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_hping_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Normal use of hping is uncommon apart from security testing and research. Use by non-security engineers is very uncommon." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -25,5 +26,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_iodine_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_iodine_activity.json index 73bf20a5a175e..63c82c5662df6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_iodine_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_iodine_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Normal use of Iodine is uncommon apart from security testing and research. Use by non-security engineers is very uncommon." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -25,5 +26,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json index 1895caf4dea81..37d5468c773bf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_mknod_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Mknod is a Linux system program. Some normal use of this program, at varying levels of frequency, may originate from scripts, automation tools, and frameworks. Usage by web servers is more likely to be suspicious." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -25,5 +26,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_netcat_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_netcat_network_connection.json index ac46bcbdbc083..bce10f640691b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_netcat_network_connection.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_netcat_network_connection.json @@ -6,6 +6,7 @@ "false_positives": [ "Netcat is a dual-use tool that can be used for benign or malicious activity. Netcat is included in some Linux distributions so its presence is not necessarily suspicious. Some normal use of this program, while uncommon, may originate from scripts, automation tools, and frameworks." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -27,5 +28,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json index 2825dc28ad18f..5d9e338425bda 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nmap_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Security testing tools and frameworks may run `Nmap` in the course of security auditing. Some normal use of this command may originate from security engineers and network or server administrators. Use of nmap by ordinary users is uncommon." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -25,5 +26,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nping_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nping_activity.json index 234a09e9607b9..bd019c9a80c4c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nping_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_nping_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Some normal use of this command may originate from security engineers and network or server administrators, but this is usually not routine or unannounced. Use of `Nping` by non-engineers or ordinary users is uncommon." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -25,5 +26,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_process_started_in_temp_directory.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_process_started_in_temp_directory.json index 759622804444e..f0bbc892d7d9c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_process_started_in_temp_directory.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_process_started_in_temp_directory.json @@ -6,6 +6,7 @@ "false_positives": [ "Build systems, like Jenkins, may start processes in the `/tmp` directory. These can be exempted by name or by username." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -22,5 +23,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json index cd38aff3f2164..fac03d31b57bf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_socat_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Socat is a dual-use tool that can be used for benign or malicious activity. Some normal use of this program, at varying levels of frequency, may originate from scripts, automation tools, and frameworks. Usage by web servers is more likely to be suspicious." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -25,5 +26,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_strace_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_strace_activity.json index 7fcb9f915c560..c1b782d612ccb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_strace_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/linux_strace_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Strace is a dual-use tool that can be used for benign or malicious activity. Some normal use of this command may originate from developers or SREs engaged in debugging or system call tracing." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -25,5 +26,5 @@ "Linux" ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json index 3392a1bff23b8..a4c62b98fb060 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Detects writing executable files that will be automatically launched by Adobe on launch.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json index e76379d171bf7..e3dedeef07eb5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kernel_module_activity.json @@ -6,6 +6,7 @@ "false_positives": [ "Security tools and device drivers may run these programs in order to load legitimate kernel modules. Use of these programs by ordinary users is uncommon." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -42,5 +43,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_commands.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_commands.json index b9e7f941ee5df..8b81789f6aa8f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_commands.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_commands.json @@ -6,6 +6,7 @@ "false_positives": [ "Legitimate scheduled tasks may be created during installation of new software." ], + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -39,5 +40,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json index 0cf6fcdb3875a..2aaf0012acabf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json @@ -6,6 +6,7 @@ "false_positives": [ "Network monitoring or management products may have a web server component that runs shell commands as part of normal behavior." ], + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -42,5 +43,5 @@ } ], "type": "query", - "version": 4 + "version": 5 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json index 59715dae441f4..32d78480325e6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Windows services typically run as SYSTEM and can be used as a privilege escalation opportunity. Malware or penetration testers may run a shell as a service to gain SYSTEM permissions.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json index 7465751d5cd49..3f2e00f0976de 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies attempts to create new local users. This is sometimes done by attackers to increase access to a system or domain.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setgid_bit_set_via_chmod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setgid_bit_set_via_chmod.json index 9550eea6ca6aa..bb0856c0452d5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setgid_bit_set_via_chmod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setgid_bit_set_via_chmod.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "An adversary may add the setgid bit to a file or directory in order to run a file with the privileges of the owning group. An adversary can take advantage of this to either do a shell escape or exploit a vulnerability in an application with the setgid bit to get code running in a different user\u2019s context. Additionally, adversaries can use this mechanism on their own malware to make sure they're able to execute in elevated contexts in the future.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -52,5 +53,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_bit_set_via_chmod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_bit_set_via_chmod.json index 343426953add6..4cf60d2c9d0de 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_bit_set_via_chmod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_bit_set_via_chmod.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "An adversary may add the setuid bit to a file or directory in order to run a file with the privileges of the owning user. An adversary can take advantage of this to either do a shell escape or exploit a vulnerability in an application with the setuid bit to get code running in a different user\u2019s context. Additionally, adversaries can use this mechanism on their own malware to make sure they're able to execute in elevated contexts in the future.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -52,5 +53,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json index 44b50c74bafe6..73a804fcbda8f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "A sudoers file specifies the commands that users or groups can run and from which terminals. Adversaries can take advantage of these configurations to execute commands as other users or spawn processes with higher privileges.", + "from": "now-9m", "index": [ "auditbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json index 50692dae3856f..740ff47e5abe5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies User Account Control (UAC) bypass via eventvwr.exe. Attackers bypass UAC to stealthily execute code with elevated permissions.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 2 + "version": 3 } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json index 8f938c0ceee6d..c6c5cbce2c095 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json @@ -3,6 +3,7 @@ "Elastic" ], "description": "Identifies Windows programs run from unexpected parent processes. This could indicate masquerading or other strange activity on a system.", + "from": "now-9m", "index": [ "winlogbeat-*", "logs-endpoint.events.*" @@ -36,5 +37,5 @@ } ], "type": "query", - "version": 3 + "version": 4 } diff --git a/x-pack/plugins/security_solution/server/lib/index_fields/elasticsearch_adapter.test.ts b/x-pack/plugins/security_solution/server/lib/index_fields/elasticsearch_adapter.test.ts index 20bc1387a3c4e..e8883111c95f6 100644 --- a/x-pack/plugins/security_solution/server/lib/index_fields/elasticsearch_adapter.test.ts +++ b/x-pack/plugins/security_solution/server/lib/index_fields/elasticsearch_adapter.test.ts @@ -6,16 +6,21 @@ import { sortBy } from 'lodash/fp'; -import { formatIndexFields } from './elasticsearch_adapter'; +import { + formatIndexFields, + formatFirstFields, + formatSecondFields, + createFieldItem, +} from './elasticsearch_adapter'; import { mockAuditbeatIndexField, mockFilebeatIndexField, mockPacketbeatIndexField } from './mock'; describe('Index Fields', () => { describe('formatIndexFields', () => { - test('Test Basic functionality', async () => { + test('Basic functionality', async () => { expect( sortBy( 'name', - formatIndexFields( + await formatIndexFields( [mockAuditbeatIndexField, mockFilebeatIndexField, mockPacketbeatIndexField], ['auditbeat', 'filebeat', 'packetbeat'] ) @@ -130,4 +135,557 @@ describe('Index Fields', () => { ); }); }); + + describe('formatFirstFields', () => { + test('Basic functionality', async () => { + const fields = await formatFirstFields( + [mockAuditbeatIndexField, mockFilebeatIndexField, mockPacketbeatIndexField], + ['auditbeat', 'filebeat', 'packetbeat'] + ); + expect(fields).toEqual([ + { + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + footnote: '', + group: 1, + level: 'core', + name: '_id', + required: true, + type: 'string', + searchable: true, + aggregatable: false, + readFromDocValues: true, + category: '_id', + indexes: ['auditbeat'], + }, + { + description: + 'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.', + example: 'auditbeat-8.0.0-2019.02.19-000001', + footnote: '', + group: 1, + level: 'core', + name: '_index', + required: true, + type: 'string', + searchable: true, + aggregatable: true, + readFromDocValues: true, + category: '_index', + indexes: ['auditbeat'], + }, + { + description: + 'Date/time when the event originated.\n\nThis is the date/time extracted from the event, typically representing when\nthe event was generated by the source.\n\nIf the event source has no original timestamp, this value is typically populated\nby the first time the event was received by the pipeline.\n\nRequired field for all events.', + example: '2016-05-23T08:05:34.853Z', + name: '@timestamp', + type: 'date', + searchable: true, + aggregatable: true, + category: 'base', + indexes: ['auditbeat'], + }, + { + description: + 'Ephemeral identifier of this agent (if one exists).\n\nThis id normally changes across restarts, but `agent.id` does not.', + example: '8a4f500f', + name: 'agent.ephemeral_id', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: + 'Custom name of the agent.\n\nThis is a name that can be given to an agent. This can be helpful if for example\ntwo Filebeat instances are running on the same host but a human readable separation\nis needed on which Filebeat instance data is coming from.\n\nIf no name is given, the name is often left empty.', + example: 'foo', + name: 'agent.name', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: + 'Type of the agent.\n\nThe agent type stays always the same and should be given by the agent used.\nIn case of Filebeat the agent would always be Filebeat also if two Filebeat\ninstances are run on the same machine.', + example: 'filebeat', + name: 'agent.type', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: 'Version of the agent.', + example: '6.0.0-rc2', + name: 'agent.version', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + footnote: '', + group: 1, + level: 'core', + name: '_id', + required: true, + type: 'string', + searchable: true, + aggregatable: false, + readFromDocValues: true, + category: '_id', + indexes: ['filebeat'], + }, + { + description: + 'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.', + example: 'auditbeat-8.0.0-2019.02.19-000001', + footnote: '', + group: 1, + level: 'core', + name: '_index', + required: true, + type: 'string', + searchable: true, + aggregatable: true, + readFromDocValues: true, + category: '_index', + indexes: ['filebeat'], + }, + { + description: + 'Date/time when the event originated.\n\nThis is the date/time extracted from the event, typically representing when\nthe event was generated by the source.\n\nIf the event source has no original timestamp, this value is typically populated\nby the first time the event was received by the pipeline.\n\nRequired field for all events.', + example: '2016-05-23T08:05:34.853Z', + name: '@timestamp', + type: 'date', + searchable: true, + aggregatable: true, + category: 'base', + indexes: ['filebeat'], + }, + { + name: 'agent.hostname', + searchable: true, + type: 'string', + aggregatable: true, + category: 'agent', + indexes: ['filebeat'], + }, + { + description: + 'Custom name of the agent.\n\nThis is a name that can be given to an agent. This can be helpful if for example\ntwo Filebeat instances are running on the same host but a human readable separation\nis needed on which Filebeat instance data is coming from.\n\nIf no name is given, the name is often left empty.', + example: 'foo', + name: 'agent.name', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['filebeat'], + }, + { + description: 'Version of the agent.', + example: '6.0.0-rc2', + name: 'agent.version', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['filebeat'], + }, + { + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + footnote: '', + group: 1, + level: 'core', + name: '_id', + required: true, + type: 'string', + searchable: true, + aggregatable: false, + readFromDocValues: true, + category: '_id', + indexes: ['packetbeat'], + }, + { + description: + 'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.', + example: 'auditbeat-8.0.0-2019.02.19-000001', + footnote: '', + group: 1, + level: 'core', + name: '_index', + required: true, + type: 'string', + searchable: true, + aggregatable: true, + readFromDocValues: true, + category: '_index', + indexes: ['packetbeat'], + }, + { + description: + 'Date/time when the event originated.\n\nThis is the date/time extracted from the event, typically representing when\nthe event was generated by the source.\n\nIf the event source has no original timestamp, this value is typically populated\nby the first time the event was received by the pipeline.\n\nRequired field for all events.', + example: '2016-05-23T08:05:34.853Z', + name: '@timestamp', + type: 'date', + searchable: true, + aggregatable: true, + category: 'base', + indexes: ['packetbeat'], + }, + { + description: + 'Unique identifier of this agent (if one exists).\n\nExample: For Beats this would be beat.id.', + example: '8a4f500d', + name: 'agent.id', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['packetbeat'], + }, + { + description: + 'Type of the agent.\n\nThe agent type stays always the same and should be given by the agent used.\nIn case of Filebeat the agent would always be Filebeat also if two Filebeat\ninstances are run on the same machine.', + example: 'filebeat', + name: 'agent.type', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['packetbeat'], + }, + ]); + }); + }); + + describe('formatSecondFields', () => { + test('Basic functionality', async () => { + const fields = await formatSecondFields([ + { + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + name: '_id', + type: 'string', + searchable: true, + aggregatable: false, + category: '_id', + indexes: ['auditbeat'], + }, + { + description: + 'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.', + example: 'auditbeat-8.0.0-2019.02.19-000001', + name: '_index', + type: 'string', + searchable: true, + aggregatable: true, + category: '_index', + indexes: ['auditbeat'], + }, + { + description: + 'Date/time when the event originated.\n\nThis is the date/time extracted from the event, typically representing when\nthe event was generated by the source.\n\nIf the event source has no original timestamp, this value is typically populated\nby the first time the event was received by the pipeline.\n\nRequired field for all events.', + example: '2016-05-23T08:05:34.853Z', + name: '@timestamp', + type: 'date', + searchable: true, + aggregatable: true, + category: 'base', + indexes: ['auditbeat'], + }, + { + description: + 'Ephemeral identifier of this agent (if one exists).\n\nThis id normally changes across restarts, but `agent.id` does not.', + example: '8a4f500f', + name: 'agent.ephemeral_id', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: + 'Custom name of the agent.\n\nThis is a name that can be given to an agent. This can be helpful if for example\ntwo Filebeat instances are running on the same host but a human readable separation\nis needed on which Filebeat instance data is coming from.\n\nIf no name is given, the name is often left empty.', + example: 'foo', + name: 'agent.name', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: + 'Type of the agent.\n\nThe agent type stays always the same and should be given by the agent used.\nIn case of Filebeat the agent would always be Filebeat also if two Filebeat\ninstances are run on the same machine.', + example: 'filebeat', + name: 'agent.type', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: 'Version of the agent.', + example: '6.0.0-rc2', + name: 'agent.version', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + name: '_id', + type: 'string', + searchable: true, + aggregatable: false, + category: '_id', + indexes: ['filebeat'], + }, + { + description: + 'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.', + example: 'auditbeat-8.0.0-2019.02.19-000001', + name: '_index', + type: 'string', + searchable: true, + aggregatable: true, + category: '_index', + indexes: ['filebeat'], + }, + { + description: + 'Date/time when the event originated.\n\nThis is the date/time extracted from the event, typically representing when\nthe event was generated by the source.\n\nIf the event source has no original timestamp, this value is typically populated\nby the first time the event was received by the pipeline.\n\nRequired field for all events.', + example: '2016-05-23T08:05:34.853Z', + name: '@timestamp', + type: 'date', + searchable: true, + aggregatable: true, + category: 'base', + indexes: ['filebeat'], + }, + { + name: 'agent.hostname', + searchable: true, + type: 'string', + aggregatable: true, + category: 'agent', + indexes: ['filebeat'], + }, + { + description: + 'Custom name of the agent.\n\nThis is a name that can be given to an agent. This can be helpful if for example\ntwo Filebeat instances are running on the same host but a human readable separation\nis needed on which Filebeat instance data is coming from.\n\nIf no name is given, the name is often left empty.', + example: 'foo', + name: 'agent.name', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['filebeat'], + }, + { + description: 'Version of the agent.', + example: '6.0.0-rc2', + name: 'agent.version', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['filebeat'], + }, + { + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + name: '_id', + type: 'string', + searchable: true, + aggregatable: false, + category: '_id', + indexes: ['packetbeat'], + }, + { + description: + 'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.', + example: 'auditbeat-8.0.0-2019.02.19-000001', + name: '_index', + type: 'string', + searchable: true, + aggregatable: true, + category: '_index', + indexes: ['packetbeat'], + }, + { + description: + 'Date/time when the event originated.\n\nThis is the date/time extracted from the event, typically representing when\nthe event was generated by the source.\n\nIf the event source has no original timestamp, this value is typically populated\nby the first time the event was received by the pipeline.\n\nRequired field for all events.', + example: '2016-05-23T08:05:34.853Z', + name: '@timestamp', + type: 'date', + searchable: true, + aggregatable: true, + category: 'base', + indexes: ['packetbeat'], + }, + { + description: + 'Unique identifier of this agent (if one exists).\n\nExample: For Beats this would be beat.id.', + example: '8a4f500d', + name: 'agent.id', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['packetbeat'], + }, + { + description: + 'Type of the agent.\n\nThe agent type stays always the same and should be given by the agent used.\nIn case of Filebeat the agent would always be Filebeat also if two Filebeat\ninstances are run on the same machine.', + example: 'filebeat', + name: 'agent.type', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['packetbeat'], + }, + ]); + expect(fields).toEqual([ + { + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + name: '_id', + type: 'string', + searchable: true, + aggregatable: false, + category: '_id', + indexes: ['auditbeat', 'filebeat', 'packetbeat'], + }, + { + description: + 'An index is like a ‘database’ in a relational database. It has a mapping which defines multiple types. An index is a logical namespace which maps to one or more primary shards and can have zero or more replica shards.', + example: 'auditbeat-8.0.0-2019.02.19-000001', + name: '_index', + type: 'string', + searchable: true, + aggregatable: true, + category: '_index', + indexes: ['auditbeat', 'filebeat', 'packetbeat'], + }, + { + description: + 'Date/time when the event originated.\n\nThis is the date/time extracted from the event, typically representing when\nthe event was generated by the source.\n\nIf the event source has no original timestamp, this value is typically populated\nby the first time the event was received by the pipeline.\n\nRequired field for all events.', + example: '2016-05-23T08:05:34.853Z', + name: '@timestamp', + type: 'date', + searchable: true, + aggregatable: true, + category: 'base', + indexes: ['auditbeat', 'filebeat', 'packetbeat'], + }, + { + description: + 'Ephemeral identifier of this agent (if one exists).\n\nThis id normally changes across restarts, but `agent.id` does not.', + example: '8a4f500f', + name: 'agent.ephemeral_id', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat'], + }, + { + description: + 'Custom name of the agent.\n\nThis is a name that can be given to an agent. This can be helpful if for example\ntwo Filebeat instances are running on the same host but a human readable separation\nis needed on which Filebeat instance data is coming from.\n\nIf no name is given, the name is often left empty.', + example: 'foo', + name: 'agent.name', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat', 'filebeat'], + }, + { + description: + 'Type of the agent.\n\nThe agent type stays always the same and should be given by the agent used.\nIn case of Filebeat the agent would always be Filebeat also if two Filebeat\ninstances are run on the same machine.', + example: 'filebeat', + name: 'agent.type', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat', 'packetbeat'], + }, + { + description: 'Version of the agent.', + example: '6.0.0-rc2', + name: 'agent.version', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['auditbeat', 'filebeat'], + }, + { + name: 'agent.hostname', + searchable: true, + type: 'string', + aggregatable: true, + category: 'agent', + indexes: ['filebeat'], + }, + { + description: + 'Unique identifier of this agent (if one exists).\n\nExample: For Beats this would be beat.id.', + example: '8a4f500d', + name: 'agent.id', + type: 'string', + searchable: true, + aggregatable: true, + category: 'agent', + indexes: ['packetbeat'], + }, + ]); + }); + }); + + describe('createFieldItem', () => { + test('Basic functionality', () => { + const item = createFieldItem( + ['auditbeat'], + { + name: '_id', + type: 'string', + searchable: true, + aggregatable: false, + }, + 0 + ); + expect(item).toEqual({ + description: 'Each document has an _id that uniquely identifies it', + example: 'Y-6TfmcB0WOhS6qyMv3s', + footnote: '', + group: 1, + level: 'core', + name: '_id', + required: true, + type: 'string', + searchable: true, + aggregatable: false, + category: '_id', + indexes: ['auditbeat'], + }); + }); + }); }); diff --git a/x-pack/plugins/security_solution/server/lib/index_fields/elasticsearch_adapter.ts b/x-pack/plugins/security_solution/server/lib/index_fields/elasticsearch_adapter.ts index bb0a4b9e2ba9b..777b1cf3bb80d 100644 --- a/x-pack/plugins/security_solution/server/lib/index_fields/elasticsearch_adapter.ts +++ b/x-pack/plugins/security_solution/server/lib/index_fields/elasticsearch_adapter.ts @@ -4,45 +4,25 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEmpty, get } from 'lodash/fp'; +import { isEmpty } from 'lodash/fp'; import { IndexField } from '../../graphql/types'; -import { - baseCategoryFields, - getDocumentation, - getIndexAlias, - hasDocumentation, - IndexAlias, -} from '../../utils/beat_schema'; +import { baseCategoryFields, getDocumentation, hasDocumentation } from '../../utils/beat_schema'; import { FrameworkAdapter, FrameworkRequest } from '../framework'; import { FieldsAdapter, IndexFieldDescriptor } from './types'; export class ElasticsearchIndexFieldAdapter implements FieldsAdapter { constructor(private readonly framework: FrameworkAdapter) {} - public async getIndexFields(request: FrameworkRequest, indices: string[]): Promise { const indexPatternsService = this.framework.getIndexPatternsService(request); - const indexesAliasIndices = indices.reduce>((accumulator, indice) => { - const key = getIndexAlias(indices, indice); - - if (get(key, accumulator)) { - accumulator[key] = [...accumulator[key], indice]; - } else { - accumulator[key] = [indice]; - } - return accumulator; - }, {}); - const responsesIndexFields: IndexFieldDescriptor[][] = await Promise.all( - Object.values(indexesAliasIndices).map((indicesByGroup) => - indexPatternsService.getFieldsForWildcard({ - pattern: indicesByGroup, - }) - ) - ); - return formatIndexFields( - responsesIndexFields, - Object.keys(indexesAliasIndices) as IndexAlias[] + const responsesIndexFields = await Promise.all( + indices.map((index) => { + return indexPatternsService.getFieldsForWildcard({ + pattern: index, + }); + }) ); + return formatIndexFields(responsesIndexFields, indices); } } @@ -63,51 +43,128 @@ const missingFields = [ }, ]; -export const formatIndexFields = ( +/** + * Creates a single field item. + * + * This is a mutatious HOT CODE PATH function that will have array sizes up to 4.7 megs + * in size at a time calling this function repeatedly. This function should be as optimized as possible + * and should avoid any and all creation of new arrays, iterating over the arrays or performing + * any n^2 operations. + * @param indexesAlias The index alias + * @param index The index its self + * @param indexesAliasIdx The index within the alias + */ +export const createFieldItem = ( + indexesAlias: string[], + index: IndexFieldDescriptor, + indexesAliasIdx: number +): IndexField => { + const alias = indexesAlias[indexesAliasIdx]; + const splitName = index.name.split('.'); + const category = baseCategoryFields.includes(splitName[0]) ? 'base' : splitName[0]; + return { + ...(hasDocumentation(alias, index.name) ? getDocumentation(alias, index.name) : {}), + ...index, + category, + indexes: [alias], + }; +}; + +/** + * This is a mutatious HOT CODE PATH function that will have array sizes up to 4.7 megs + * in size at a time when being called. This function should be as optimized as possible + * and should avoid any and all creation of new arrays, iterating over the arrays or performing + * any n^2 operations. The `.push`, and `forEach` operations are expected within this function + * to speed up performance. + * + * This intentionally waits for the next tick on the event loop to process as the large 4.7 megs + * has already consumed a lot of the event loop processing up to this function and we want to give + * I/O opportunity to occur by scheduling this on the next loop. + * @param responsesIndexFields The response index fields to loop over + * @param indexesAlias The index aliases such as filebeat-* + */ +export const formatFirstFields = async ( responsesIndexFields: IndexFieldDescriptor[][], - indexesAlias: IndexAlias[] -): IndexField[] => - responsesIndexFields - .reduce( - (accumulator: IndexField[], indexFields: IndexFieldDescriptor[], indexesAliasIdx: number) => [ - ...accumulator, - ...[...missingFields, ...indexFields].reduce( - (itemAccumulator: IndexField[], index: IndexFieldDescriptor) => { - const alias: IndexAlias = indexesAlias[indexesAliasIdx]; - const splitName = index.name.split('.'); - const category = baseCategoryFields.includes(splitName[0]) ? 'base' : splitName[0]; - return [ - ...itemAccumulator, - { - ...(hasDocumentation(alias, index.name) ? getDocumentation(alias, index.name) : {}), - ...index, - category, - indexes: [alias], - } as IndexField, - ]; + indexesAlias: string[] +): Promise => { + return new Promise((resolve) => { + setTimeout(() => { + resolve( + responsesIndexFields.reduce( + ( + accumulator: IndexField[], + indexFields: IndexFieldDescriptor[], + indexesAliasIdx: number + ) => { + missingFields.forEach((index) => { + const item = createFieldItem(indexesAlias, index, indexesAliasIdx); + accumulator.push(item); + }); + indexFields.forEach((index) => { + const item = createFieldItem(indexesAlias, index, indexesAliasIdx); + accumulator.push(item); + }); + return accumulator; }, [] - ), - ], - [] - ) - .reduce((accumulator: IndexField[], indexfield: IndexField) => { - const alreadyExistingIndexField = accumulator.findIndex( - (acc) => acc.name === indexfield.name + ) ); - if (alreadyExistingIndexField > -1) { - const existingIndexField = accumulator[alreadyExistingIndexField]; - return [ - ...accumulator.slice(0, alreadyExistingIndexField), - { - ...existingIndexField, - description: isEmpty(existingIndexField.description) - ? indexfield.description - : existingIndexField.description, - indexes: Array.from(new Set([...existingIndexField.indexes, ...indexfield.indexes])), - }, - ...accumulator.slice(alreadyExistingIndexField + 1), - ]; - } - return [...accumulator, indexfield]; - }, []); + }); + }); +}; + +/** + * This is a mutatious HOT CODE PATH function that will have array sizes up to 4.7 megs + * in size at a time when being called. This function should be as optimized as possible + * and should avoid any and all creation of new arrays, iterating over the arrays or performing + * any n^2 operations. The `.push`, and `forEach` operations are expected within this function + * to speed up performance. The "indexFieldNameHash" side effect hash avoids additional expensive n^2 + * look ups. + * + * This intentionally waits for the next tick on the event loop to process as the large 4.7 megs + * has already consumed a lot of the event loop processing up to this function and we want to give + * I/O opportunity to occur by scheduling this on the next loop. + * @param fields The index fields to create the secondary fields for + */ +export const formatSecondFields = async (fields: IndexField[]): Promise => { + return new Promise((resolve) => { + setTimeout(() => { + const indexFieldNameHash: Record = {}; + const reduced = fields.reduce((accumulator: IndexField[], indexfield: IndexField) => { + const alreadyExistingIndexField = indexFieldNameHash[indexfield.name]; + if (alreadyExistingIndexField != null) { + const existingIndexField = accumulator[alreadyExistingIndexField]; + if (isEmpty(accumulator[alreadyExistingIndexField].description)) { + accumulator[alreadyExistingIndexField].description = indexfield.description; + } + accumulator[alreadyExistingIndexField].indexes = Array.from( + new Set([...existingIndexField.indexes, ...indexfield.indexes]) + ); + return accumulator; + } + accumulator.push(indexfield); + indexFieldNameHash[indexfield.name] = accumulator.length - 1; + return accumulator; + }, []); + resolve(reduced); + }); + }); +}; + +/** + * Formats the index fields into a format the UI wants. + * + * NOTE: This will have array sizes up to 4.7 megs in size at a time when being called. + * This function should be as optimized as possible and should avoid any and all creation + * of new arrays, iterating over the arrays or performing any n^2 operations. + * @param responsesIndexFields The response index fields to format + * @param indexesAlias The index alias + */ +export const formatIndexFields = async ( + responsesIndexFields: IndexFieldDescriptor[][], + indexesAlias: string[] +): Promise => { + const fields = await formatFirstFields(responsesIndexFields, indexesAlias); + const secondFields = await formatSecondFields(fields); + return secondFields; +}; diff --git a/x-pack/plugins/security_solution/server/utils/beat_schema/index.test.ts b/x-pack/plugins/security_solution/server/utils/beat_schema/index.test.ts index 5f002aa7fad7b..29944edf382f4 100644 --- a/x-pack/plugins/security_solution/server/utils/beat_schema/index.test.ts +++ b/x-pack/plugins/security_solution/server/utils/beat_schema/index.test.ts @@ -6,7 +6,7 @@ import { cloneDeep, isArray } from 'lodash/fp'; -import { convertSchemaToAssociativeArray, getIndexSchemaDoc, getIndexAlias } from '.'; +import { convertSchemaToAssociativeArray, getIndexSchemaDoc } from '.'; import { auditbeatSchema, filebeatSchema, packetbeatSchema } from './8.0.0'; import { Schema } from './type'; @@ -394,24 +394,4 @@ describe('Schema Beat', () => { ]); }); }); - - describe('getIndexAlias', () => { - test('getIndexAlias handles values with leading wildcard', () => { - const leadingWildcardIndex = '*-auditbeat-*'; - const result = getIndexAlias([leadingWildcardIndex], leadingWildcardIndex); - expect(result).toBe(leadingWildcardIndex); - }); - - test('getIndexAlias no match returns "unknown" string', () => { - const index = 'auditbeat-*'; - const result = getIndexAlias([index], 'hello'); - expect(result).toBe('unknown'); - }); - - test('empty index should not cause an error to return although it will cause an invalid regular expression to occur', () => { - const index = ''; - const result = getIndexAlias([index], 'hello'); - expect(result).toBe('unknown'); - }); - }); }); diff --git a/x-pack/plugins/security_solution/server/utils/beat_schema/index.ts b/x-pack/plugins/security_solution/server/utils/beat_schema/index.ts index 6ec15d328714d..58627a199a181 100644 --- a/x-pack/plugins/security_solution/server/utils/beat_schema/index.ts +++ b/x-pack/plugins/security_solution/server/utils/beat_schema/index.ts @@ -76,21 +76,6 @@ const convertFieldsToAssociativeArray = ( }, {}) : {}; -export const getIndexAlias = (defaultIndex: string[], indexName: string): string => { - try { - const found = defaultIndex.find((index) => `\\${indexName}`.match(`\\${index}`) != null); - if (found != null) { - return found; - } else { - return 'unknown'; - } - } catch (error) { - // if we encounter an error because the index contains invalid regular expressions then we should return an unknown - // rather than blow up with a toaster error upstream - return 'unknown'; - } -}; - export const getIndexSchemaDoc = memoize((index: string) => { if (index.match('auditbeat') != null) { return { diff --git a/x-pack/plugins/security_solution/server/utils/beat_schema/type.ts b/x-pack/plugins/security_solution/server/utils/beat_schema/type.ts index 2b7be8f4b7539..722589ce7e2bb 100644 --- a/x-pack/plugins/security_solution/server/utils/beat_schema/type.ts +++ b/x-pack/plugins/security_solution/server/utils/beat_schema/type.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export type IndexAlias = 'auditbeat' | 'filebeat' | 'packetbeat' | 'ecs' | 'winlogbeat' | 'unknown'; - /* * BEAT Interface * diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 616d226c4cbea..ca9b45493faae 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2775,14 +2775,6 @@ "inspector.requests.statisticsTabLabel": "統計", "inspector.title": "インスペクター", "inspector.view": "{viewName} を表示", - "kbn.advancedSettings.visualization.showRegionMapWarningsText": "用語がマップの形に合わない場合に地域マップに警告を表示するかどうかです。", - "kbn.advancedSettings.visualization.showRegionMapWarningsTitle": "地域マップに警告を表示", - "kbn.advancedSettings.visualization.tileMap.maxPrecision.cellDimensionsLinkText": "ディメンションの説明", - "kbn.advancedSettings.visualization.tileMap.maxPrecisionText": "マップに表示されるジオハッシュの最高精度です。7 が高い、10 が非常に高い、12 が最高を意味します。{cellDimensionsLink}", - "kbn.advancedSettings.visualization.tileMap.maxPrecisionTitle": "タイルマップの最高精度", - "kbn.advancedSettings.visualization.tileMap.wmsDefaults.propertiesLinkText": "プロパティ", - "kbn.advancedSettings.visualization.tileMap.wmsDefaultsText": "座標マップの WMS マップサーバーサポートのデフォルトの {propertiesLink} です。", - "kbn.advancedSettings.visualization.tileMap.wmsDefaultsTitle": "デフォルトの WMS プロパティ", "kibana_legacy.notify.fatalError.errorStatusMessage": "エラー {errStatus} {errStatusText}: {errMessage}", "kibana_legacy.notify.fatalError.unavailableServerErrorMessage": "HTTP リクエストで接続に失敗しました。Kibana サーバーが実行されていて、ご使用のブラウザの接続が正常に動作していることを確認するか、システム管理者にお問い合わせください。", "kibana_legacy.notify.toaster.errorMessage": "エラー: {errorMessage}\n {errorStack}", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index d2d49da0dc411..322efcbccdfd7 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2776,14 +2776,6 @@ "inspector.requests.statisticsTabLabel": "统计信息", "inspector.title": "检查器", "inspector.view": "视图:{viewName}", - "kbn.advancedSettings.visualization.showRegionMapWarningsText": "词无法联接到地图上的形状时,区域地图是否显示警告。", - "kbn.advancedSettings.visualization.showRegionMapWarningsTitle": "显示区域地图警告", - "kbn.advancedSettings.visualization.tileMap.maxPrecision.cellDimensionsLinkText": "单元格维度的解释", - "kbn.advancedSettings.visualization.tileMap.maxPrecisionText": "在磁贴地图上显示的最大 geoHash 精确度:7 为高,10 为很高,12 为最大值。{cellDimensionsLink}", - "kbn.advancedSettings.visualization.tileMap.maxPrecisionTitle": "最大磁贴地图精确度", - "kbn.advancedSettings.visualization.tileMap.wmsDefaults.propertiesLinkText": "属性", - "kbn.advancedSettings.visualization.tileMap.wmsDefaultsText": "坐标地图中 WMS 地图服务器支持的默认{propertiesLink}", - "kbn.advancedSettings.visualization.tileMap.wmsDefaultsTitle": "默认 WMS 属性", "kibana_legacy.notify.fatalError.errorStatusMessage": "错误 {errStatus} {errStatusText}:{errMessage}", "kibana_legacy.notify.fatalError.unavailableServerErrorMessage": "HTTP 请求无法连接。请检查 Kibana 服务器是否正在运行以及您的浏览器是否具有有效的连接,或请联系您的系统管理员。", "kibana_legacy.notify.toaster.errorMessage": "错误:{errorMessage}\n {errorStack}", diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index f2dcf28c01743..d1ecf8fa0973a 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -31,6 +31,9 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./dashboard')); loadTestFile(require.resolve('./persistent_context')); loadTestFile(require.resolve('./lens_reporting')); + + // has to be last one in the suite because it overrides saved objects + loadTestFile(require.resolve('./rollup')); }); }); } diff --git a/x-pack/test/functional/apps/lens/rollup.ts b/x-pack/test/functional/apps/lens/rollup.ts new file mode 100644 index 0000000000000..f6882c8aed214 --- /dev/null +++ b/x-pack/test/functional/apps/lens/rollup.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['visualize', 'lens']); + const find = getService('find'); + const listingTable = getService('listingTable'); + const esArchiver = getService('esArchiver'); + + describe('lens rollup tests', () => { + before(async () => { + await esArchiver.loadIfNeeded('lens/rollup/data'); + await esArchiver.loadIfNeeded('lens/rollup/config'); + }); + + after(async () => { + await esArchiver.unload('lens/rollup/data'); + await esArchiver.unload('lens/rollup/config'); + }); + + it('should allow creation of lens xy chart', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + await PageObjects.lens.goToTimeRange(); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + field: '@timestamp', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'sum', + field: 'bytes', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_splitDimensionPanel > lns-empty-dimension', + operation: 'terms', + field: 'geo.src', + }); + expect(await find.allByCssSelector('.echLegendItem')).to.have.length(2); + + await PageObjects.lens.save('Afancilenstest'); + + // Ensure the visualization shows up in the visualize list, and takes + // us back to the visualization as we configured it. + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('Afancilenstest'); + await PageObjects.lens.clickVisualizeListItemTitle('Afancilenstest'); + await PageObjects.lens.goToTimeRange(); + + expect(await PageObjects.lens.getTitle()).to.eql('Afancilenstest'); + + // .echLegendItem__title is the only viable way of getting the xy chart's + // legend item(s), so we're using a class selector here. + expect(await find.allByCssSelector('.echLegendItem')).to.have.length(2); + }); + + it('should allow seamless transition to and from table view', async () => { + await PageObjects.lens.switchToVisualization('lnsMetric'); + await PageObjects.lens.assertMetric('Sum of bytes', '16,788'); + await PageObjects.lens.switchToVisualization('lnsDatatable'); + expect(await PageObjects.lens.getDatatableHeaderText()).to.eql('Sum of bytes'); + expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('16,788'); + }); + }); +} diff --git a/x-pack/test/functional/es_archives/lens/rollup/config/data.json b/x-pack/test/functional/es_archives/lens/rollup/config/data.json new file mode 100644 index 0000000000000..268b98542fe11 --- /dev/null +++ b/x-pack/test/functional/es_archives/lens/rollup/config/data.json @@ -0,0 +1,65 @@ +{ + "type": "doc", + "value": { + "id": "space:default", + "index": ".kibana_1", + "source": { + "migrationVersion": { + "space": "6.6.0" + }, + "references": [], + "space": { + "_reserved": true, + "description": "This is the default space!", + "disabledFeatures": [], + "name": "Default" + }, + "type": "space" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "id": "index-pattern:lens-rolled-up-data", + "index": ".kibana_1", + "source": { + "index-pattern" : { + "title" : "lens_rolled_up_data", + "timeFieldName" : "@timestamp", + "fields" : "[{\"count\":0,\"name\":\"_source\",\"type\":\"_source\",\"esTypes\":[\"_source\"],\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_id\",\"type\":\"string\",\"esTypes\":[\"_id\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_type\",\"type\":\"string\",\"esTypes\":[\"_type\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_index\",\"type\":\"string\",\"esTypes\":[\"_index\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_score\",\"type\":\"number\",\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"@timestamp\",\"type\":\"date\",\"esTypes\":[\"date\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"bytes\",\"type\":\"number\",\"esTypes\":[\"float\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"geo.src\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]", + "type" : "rollup", + "typeMeta" : "{\"params\":{\"rollup_index\":\"lens_rolled_up_data\"},\"aggs\":{\"date_histogram\":{\"@timestamp\":{\"agg\":\"date_histogram\",\"fixed_interval\":\"60m\",\"time_zone\":\"UTC\"}},\"sum\":{\"bytes\":{\"agg\":\"sum\"}},\"max\":{\"bytes\":{\"agg\":\"max\"}},\"terms\":{\"geo.src\":{\"agg\":\"terms\"}}}}" + }, + "type" : "index-pattern", + "references" : [ ], + "migrationVersion" : { + "index-pattern" : "7.6.0" + }, + "updated_at" : "2020-08-19T08:39:09.998Z" + }, + "type": "_doc" + } +} + +{ + "type": "doc", + "value": { + "id": "config:8.0.0", + "index": ".kibana_1", + "source": { + "config": { + "accessibility:disableAnimations": true, + "buildNum": 9007199254740991, + "dateFormat:tz": "UTC", + "defaultIndex": "logstash-*" + }, + "references": [], + "type": "config", + "updated_at": "2019-09-04T18:47:24.761Z" + }, + "type": "_doc" + } +} diff --git a/x-pack/test/functional/es_archives/lens/rollup/config/mappings.json b/x-pack/test/functional/es_archives/lens/rollup/config/mappings.json new file mode 100644 index 0000000000000..f2a29f022ff5e --- /dev/null +++ b/x-pack/test/functional/es_archives/lens/rollup/config/mappings.json @@ -0,0 +1,1294 @@ +{ + "type": "index", + "value": { + "aliases": { + ".kibana": { + } + }, + "index": ".kibana_1", + "mappings": { + "_meta": { + "migrationMappingPropertyHashes": { + "apm-telemetry": "07ee1939fa4302c62ddc052ec03fed90", + "canvas-element": "7390014e1091044523666d97247392fc", + "canvas-workpad": "b0a1706d356228dbdcb4a17e6b9eb231", + "config": "87aca8fdb053154f11383fce3dbf3edf", + "dashboard": "d00f614b29a80360e1190193fd333bab", + "file-upload-telemetry": "0ed4d3e1983d1217a30982630897092e", + "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1", + "index-pattern": "66eccb05066c5a89924f48a9e9736499", + "infrastructure-ui-source": "ddc0ecb18383f6b26101a2fadb2dab0c", + "inventory-view": "84b320fd67209906333ffce261128462", + "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", + "lens": "21c3ea0763beb1ecb0162529706b88c5", + "map": "23d7aa4a720d4938ccde3983f87bd58d", + "maps-telemetry": "a4229f8b16a6820c6d724b7e0c1f729d", + "metrics-explorer-view": "53c5365793677328df0ccb6138bf3cdd", + "migrationVersion": "4a1746014a75ade3a714e1db5763276f", + "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9", + "namespace": "2f4316de49999235636386fe51dc06c1", + "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9", + "references": "7997cf5a56cc02bdc9c93361bde732b0", + "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4", + "search": "181661168bbadd1eff5902361e2a0d5c", + "server": "ec97f1c5da1a19609a60874e5af1100c", + "siem-ui-timeline": "1f6f0860ad7bc0dba3e42467ca40470d", + "siem-ui-timeline-note": "8874706eedc49059d4cf0f5094559084", + "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29", + "space": "c5ca8acafa0beaa4d08d014a97b6bc6b", + "telemetry": "e1c8bc94e443aefd9458932cc0697a4d", + "timelion-sheet": "9a2a2748877c7a7b582fef201ab1d4cf", + "type": "2f4316de49999235636386fe51dc06c1", + "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", + "updated_at": "00da57df13e94e9d98437d13ace4bfe0", + "upgrade-assistant-reindex-operation": "a53a20fe086b72c9a86da3cc12dad8a6", + "upgrade-assistant-telemetry": "56702cec857e0a9dacfb696655b4ff7b", + "url": "c7f66a0df8b1b52f17c28c4adb111105", + "visualization": "52d7a13ad68a150c4525b292d23e12cc" + } + }, + "dynamic": "strict", + "properties": { + "action": { + "properties": { + "actionTypeId": { + "type": "keyword" + }, + "config": { + "enabled": false, + "type": "object" + }, + "description": { + "type": "text" + }, + "secrets": { + "type": "binary" + } + } + }, + "action_task_params": { + "properties": { + "actionId": { + "type": "keyword" + }, + "apiKey": { + "type": "binary" + }, + "params": { + "enabled": false, + "type": "object" + } + } + }, + "alert": { + "properties": { + "actions": { + "properties": { + "actionRef": { + "type": "keyword" + }, + "group": { + "type": "keyword" + }, + "params": { + "enabled": false, + "type": "object" + } + }, + "type": "nested" + }, + "alertTypeId": { + "type": "keyword" + }, + "params": { + "enabled": false, + "type": "object" + }, + "apiKey": { + "type": "binary" + }, + "apiKeyOwner": { + "type": "keyword" + }, + "createdBy": { + "type": "keyword" + }, + "enabled": { + "type": "boolean" + }, + "interval": { + "type": "keyword" + }, + "scheduledTaskId": { + "type": "keyword" + }, + "updatedBy": { + "type": "keyword" + } + } + }, + "apm-telemetry": { + "properties": { + "has_any_services": { + "type": "boolean" + }, + "services_per_agent": { + "properties": { + "dotnet": { + "null_value": 0, + "type": "long" + }, + "go": { + "null_value": 0, + "type": "long" + }, + "java": { + "null_value": 0, + "type": "long" + }, + "js-base": { + "null_value": 0, + "type": "long" + }, + "nodejs": { + "null_value": 0, + "type": "long" + }, + "python": { + "null_value": 0, + "type": "long" + }, + "ruby": { + "null_value": 0, + "type": "long" + }, + "rum-js": { + "null_value": 0, + "type": "long" + } + } + } + } + }, + "canvas-element": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "content": { + "type": "text" + }, + "help": { + "type": "text" + }, + "image": { + "type": "text" + }, + "name": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "canvas-workpad": { + "dynamic": "false", + "properties": { + "@created": { + "type": "date" + }, + "@timestamp": { + "type": "date" + }, + "name": { + "fields": { + "keyword": { + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "config": { + "dynamic": "true", + "properties": { + "accessibility:disableAnimations": { + "type": "boolean" + }, + "buildNum": { + "type": "keyword" + }, + "dateFormat:tz": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "defaultIndex": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "dashboard": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } + } + }, + "optionsJSON": { + "type": "text" + }, + "panelsJSON": { + "type": "text" + }, + "refreshInterval": { + "properties": { + "display": { + "type": "keyword" + }, + "pause": { + "type": "boolean" + }, + "section": { + "type": "integer" + }, + "value": { + "type": "integer" + } + } + }, + "timeFrom": { + "type": "keyword" + }, + "timeRestore": { + "type": "boolean" + }, + "timeTo": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + } + } + }, + "file-upload-telemetry": { + "properties": { + "filesUploadedTotalCount": { + "type": "long" + } + } + }, + "gis-map": { + "properties": { + "bounds": { + "strategy": "recursive", + "type": "geo_shape" + }, + "description": { + "type": "text" + }, + "layerListJSON": { + "type": "text" + }, + "mapStateJSON": { + "type": "text" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + } + } + }, + "graph-workspace": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } + } + }, + "numLinks": { + "type": "integer" + }, + "numVertices": { + "type": "integer" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "wsState": { + "type": "text" + } + } + }, + "index-pattern": { + "properties": { + "fieldFormatMap": { + "type": "text" + }, + "fields": { + "type": "text" + }, + "intervalName": { + "type": "keyword" + }, + "notExpandable": { + "type": "boolean" + }, + "sourceFilters": { + "type": "text" + }, + "timeFieldName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "typeMeta": { + "type": "keyword" + } + } + }, + "infrastructure-ui-source": { + "properties": { + "description": { + "type": "text" + }, + "fields": { + "properties": { + "container": { + "type": "keyword" + }, + "host": { + "type": "keyword" + }, + "pod": { + "type": "keyword" + }, + "tiebreaker": { + "type": "keyword" + }, + "timestamp": { + "type": "keyword" + } + } + }, + "logAlias": { + "type": "keyword" + }, + "logColumns": { + "properties": { + "fieldColumn": { + "properties": { + "field": { + "type": "keyword" + }, + "id": { + "type": "keyword" + } + } + }, + "messageColumn": { + "properties": { + "id": { + "type": "keyword" + } + } + }, + "timestampColumn": { + "properties": { + "id": { + "type": "keyword" + } + } + } + }, + "type": "nested" + }, + "metricAlias": { + "type": "keyword" + }, + "name": { + "type": "text" + } + } + }, + "inventory-view": { + "properties": { + "autoBounds": { + "type": "boolean" + }, + "autoReload": { + "type": "boolean" + }, + "boundsOverride": { + "properties": { + "max": { + "type": "integer" + }, + "min": { + "type": "integer" + } + } + }, + "customOptions": { + "properties": { + "field": { + "type": "keyword" + }, + "text": { + "type": "keyword" + } + }, + "type": "nested" + }, + "filterQuery": { + "properties": { + "expression": { + "type": "keyword" + }, + "kind": { + "type": "keyword" + } + } + }, + "groupBy": { + "properties": { + "field": { + "type": "keyword" + }, + "label": { + "type": "keyword" + } + }, + "type": "nested" + }, + "metric": { + "properties": { + "type": { + "type": "keyword" + } + } + }, + "name": { + "type": "keyword" + }, + "nodeType": { + "type": "keyword" + }, + "time": { + "type": "integer" + }, + "view": { + "type": "keyword" + } + } + }, + "kql-telemetry": { + "properties": { + "optInCount": { + "type": "long" + }, + "optOutCount": { + "type": "long" + } + } + }, + "lens": { + "properties": { + "expression": { + "index": false, + "type": "keyword" + }, + "state": { + "type": "flattened" + }, + "title": { + "type": "text" + }, + "visualizationType": { + "type": "keyword" + } + } + }, + "map": { + "properties": { + "bounds": { + "type": "geo_shape" + }, + "description": { + "type": "text" + }, + "layerListJSON": { + "type": "text" + }, + "mapStateJSON": { + "type": "text" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + } + } + }, + "maps-telemetry": { + "properties": { + "attributesPerMap": { + "properties": { + "dataSourcesCount": { + "properties": { + "avg": { + "type": "long" + }, + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + }, + "emsVectorLayersCount": { + "dynamic": "true", + "type": "object" + }, + "layerTypesCount": { + "dynamic": "true", + "type": "object" + }, + "layersCount": { + "properties": { + "avg": { + "type": "long" + }, + "max": { + "type": "long" + }, + "min": { + "type": "long" + } + } + } + } + }, + "mapsTotalCount": { + "type": "long" + }, + "timeCaptured": { + "type": "date" + } + } + }, + "metrics-explorer-view": { + "properties": { + "chartOptions": { + "properties": { + "stack": { + "type": "boolean" + }, + "type": { + "type": "keyword" + }, + "yAxisMode": { + "type": "keyword" + } + } + }, + "currentTimerange": { + "properties": { + "from": { + "type": "keyword" + }, + "interval": { + "type": "keyword" + }, + "to": { + "type": "keyword" + } + } + }, + "name": { + "type": "keyword" + }, + "options": { + "properties": { + "aggregation": { + "type": "keyword" + }, + "filterQuery": { + "type": "keyword" + }, + "groupBy": { + "type": "keyword" + }, + "limit": { + "type": "integer" + }, + "metrics": { + "properties": { + "aggregation": { + "type": "keyword" + }, + "color": { + "type": "keyword" + }, + "field": { + "type": "keyword" + }, + "label": { + "type": "keyword" + } + }, + "type": "nested" + } + } + } + } + }, + "migrationVersion": { + "dynamic": "true", + "properties": { + "index-pattern": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "space": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "visualization": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "ml-telemetry": { + "properties": { + "file_data_visualizer": { + "properties": { + "index_creation_count": { + "type": "long" + } + } + } + } + }, + "namespace": { + "type": "keyword" + }, + "query": { + "properties": { + "description": { + "type": "text" + }, + "filters": { + "enabled": false, + "type": "object" + }, + "query": { + "properties": { + "language": { + "type": "keyword" + }, + "query": { + "index": false, + "type": "keyword" + } + } + }, + "timefilter": { + "enabled": false, + "type": "object" + }, + "title": { + "type": "text" + } + } + }, + "references": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + }, + "type": "nested" + }, + "sample-data-telemetry": { + "properties": { + "installCount": { + "type": "long" + }, + "unInstallCount": { + "type": "long" + } + } + }, + "search": { + "properties": { + "columns": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } + } + }, + "sort": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + } + } + }, + "server": { + "properties": { + "uuid": { + "type": "keyword" + } + } + }, + "siem-ui-timeline": { + "properties": { + "columns": { + "properties": { + "aggregatable": { + "type": "boolean" + }, + "category": { + "type": "keyword" + }, + "columnHeaderType": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "example": { + "type": "text" + }, + "id": { + "type": "keyword" + }, + "indexes": { + "type": "keyword" + }, + "name": { + "type": "text" + }, + "placeholder": { + "type": "text" + }, + "searchable": { + "type": "boolean" + }, + "type": { + "type": "keyword" + } + } + }, + "created": { + "type": "date" + }, + "createdBy": { + "type": "text" + }, + "dataProviders": { + "properties": { + "and": { + "properties": { + "enabled": { + "type": "boolean" + }, + "excluded": { + "type": "boolean" + }, + "id": { + "type": "keyword" + }, + "kqlQuery": { + "type": "text" + }, + "name": { + "type": "text" + }, + "queryMatch": { + "properties": { + "displayField": { + "type": "text" + }, + "displayValue": { + "type": "text" + }, + "field": { + "type": "text" + }, + "operator": { + "type": "text" + }, + "value": { + "type": "text" + } + } + } + } + }, + "enabled": { + "type": "boolean" + }, + "excluded": { + "type": "boolean" + }, + "id": { + "type": "keyword" + }, + "kqlQuery": { + "type": "text" + }, + "name": { + "type": "text" + }, + "queryMatch": { + "properties": { + "displayField": { + "type": "text" + }, + "displayValue": { + "type": "text" + }, + "field": { + "type": "text" + }, + "operator": { + "type": "text" + }, + "value": { + "type": "text" + } + } + } + } + }, + "dateRange": { + "properties": { + "end": { + "type": "date" + }, + "start": { + "type": "date" + } + } + }, + "description": { + "type": "text" + }, + "favorite": { + "properties": { + "favoriteDate": { + "type": "date" + }, + "fullName": { + "type": "text" + }, + "keySearch": { + "type": "text" + }, + "userName": { + "type": "text" + } + } + }, + "kqlMode": { + "type": "keyword" + }, + "kqlQuery": { + "properties": { + "filterQuery": { + "properties": { + "kuery": { + "properties": { + "expression": { + "type": "text" + }, + "kind": { + "type": "keyword" + } + } + }, + "serializedQuery": { + "type": "text" + } + } + } + } + }, + "sort": { + "properties": { + "columnId": { + "type": "keyword" + }, + "sortDirection": { + "type": "keyword" + } + } + }, + "title": { + "type": "text" + }, + "updated": { + "type": "date" + }, + "updatedBy": { + "type": "text" + } + } + }, + "siem-ui-timeline-note": { + "properties": { + "created": { + "type": "date" + }, + "createdBy": { + "type": "text" + }, + "eventId": { + "type": "keyword" + }, + "note": { + "type": "text" + }, + "timelineId": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "updatedBy": { + "type": "text" + } + } + }, + "siem-ui-timeline-pinned-event": { + "properties": { + "created": { + "type": "date" + }, + "createdBy": { + "type": "text" + }, + "eventId": { + "type": "keyword" + }, + "timelineId": { + "type": "keyword" + }, + "updated": { + "type": "date" + }, + "updatedBy": { + "type": "text" + } + } + }, + "space": { + "properties": { + "_reserved": { + "type": "boolean" + }, + "color": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "disabledFeatures": { + "type": "keyword" + }, + "imageUrl": { + "index": false, + "type": "text" + }, + "initials": { + "type": "keyword" + }, + "name": { + "fields": { + "keyword": { + "ignore_above": 2048, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "spaceId": { + "type": "keyword" + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "timelion-sheet": { + "properties": { + "description": { + "type": "text" + }, + "hits": { + "type": "integer" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } + } + }, + "timelion_chart_height": { + "type": "integer" + }, + "timelion_columns": { + "type": "integer" + }, + "timelion_interval": { + "type": "keyword" + }, + "timelion_other_interval": { + "type": "keyword" + }, + "timelion_rows": { + "type": "integer" + }, + "timelion_sheet": { + "type": "text" + }, + "title": { + "type": "text" + }, + "version": { + "type": "integer" + } + } + }, + "type": { + "type": "keyword" + }, + "ui-metric": { + "properties": { + "count": { + "type": "integer" + } + } + }, + "updated_at": { + "type": "date" + }, + "upgrade-assistant-reindex-operation": { + "dynamic": "true", + "properties": { + "indexName": { + "type": "keyword" + }, + "status": { + "type": "integer" + } + } + }, + "upgrade-assistant-telemetry": { + "properties": { + "features": { + "properties": { + "deprecation_logging": { + "properties": { + "enabled": { + "null_value": true, + "type": "boolean" + } + } + } + } + }, + "ui_open": { + "properties": { + "cluster": { + "null_value": 0, + "type": "long" + }, + "indices": { + "null_value": 0, + "type": "long" + }, + "overview": { + "null_value": 0, + "type": "long" + } + } + }, + "ui_reindex": { + "properties": { + "close": { + "null_value": 0, + "type": "long" + }, + "open": { + "null_value": 0, + "type": "long" + }, + "start": { + "null_value": 0, + "type": "long" + }, + "stop": { + "null_value": 0, + "type": "long" + } + } + } + } + }, + "url": { + "properties": { + "accessCount": { + "type": "long" + }, + "accessDate": { + "type": "date" + }, + "createDate": { + "type": "date" + }, + "url": { + "fields": { + "keyword": { + "ignore_above": 2048, + "type": "keyword" + } + }, + "type": "text" + } + } + }, + "visualization": { + "properties": { + "description": { + "type": "text" + }, + "kibanaSavedObjectMeta": { + "properties": { + "searchSourceJSON": { + "type": "text" + } + } + }, + "savedSearchRefName": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "uiStateJSON": { + "type": "text" + }, + "version": { + "type": "integer" + }, + "visState": { + "type": "text" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} diff --git a/x-pack/test/functional/es_archives/lens/rollup/data/data.json b/x-pack/test/functional/es_archives/lens/rollup/data/data.json new file mode 100644 index 0000000000000..36dc10c05f0b9 --- /dev/null +++ b/x-pack/test/functional/es_archives/lens/rollup/data/data.json @@ -0,0 +1,59 @@ +{ + "type": "doc", + "value": { + "index": "lens_rolled_up_data", + "id": "lens_rolled_up_data$vuSq1a9Ph2Nq-2yfGpE34g", + "source": { + "@timestamp.date_histogram.time_zone": "UTC", + "@timestamp.date_histogram.timestamp": 1442710800000, + "geo.src.terms.value": "CN", + "bytes.max.value": 5678.0, + "_rollup.version": 2, + "bytes.sum.value": 5678.0, + "@timestamp.date_histogram.interval": "60m", + "geo.src.terms._count": 1, + "@timestamp.date_histogram._count": 1, + "_rollup.id": "lens_rolled_up_data" + } + } +} + +{ + "type": "doc", + "value": { + "index": "lens_rolled_up_data", + "id": "lens_rolled_up_data$QFyUWoecErSYPMrIb6CgZA", + "source": { + "@timestamp.date_histogram.time_zone": "UTC", + "@timestamp.date_histogram.timestamp": 1442710800000, + "geo.src.terms.value": "US", + "bytes.max.value": 1234.0, + "_rollup.version": 2, + "bytes.sum.value": 1234.0, + "@timestamp.date_histogram.interval": "60m", + "geo.src.terms._count": 1, + "@timestamp.date_histogram._count": 1, + "_rollup.id": "lens_rolled_up_data" + } + } +} + +{ + "type": "doc", + "value": { + "index": "lens_rolled_up_data", + "id": "lens_rolled_up_data$cKCjv1OPjYiyv5WPPblohw", + "source": { + "@timestamp.date_histogram.time_zone": "UTC", + "@timestamp.date_histogram.timestamp": 1442714400000, + "geo.src.terms.value": "CN", + "bytes.max.value": 9876.0, + "_rollup.version": 2, + "bytes.sum.value": 9876.0, + "@timestamp.date_histogram.interval": "60m", + "geo.src.terms._count": 1, + "@timestamp.date_histogram._count": 1, + "_rollup.id": "lens_rolled_up_data" + } + } +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/lens/rollup/data/mappings.json b/x-pack/test/functional/es_archives/lens/rollup/data/mappings.json new file mode 100644 index 0000000000000..0e47a632bbf3f --- /dev/null +++ b/x-pack/test/functional/es_archives/lens/rollup/data/mappings.json @@ -0,0 +1,129 @@ +{ + "type": "index", + "value": { + "index": "lens_rolled_up_data", + "mappings": { + "_meta": { + "_rollup": { + "lens_rolled_up_data": { + "cron": "0 * * * * ?", + "rollup_index": "lens_rolled_up_data", + "groups": { + "date_histogram": { + "fixed_interval": "60m", + "field": "@timestamp", + "time_zone": "UTC" + }, + "terms": { + "fields": ["geo.src", "ip"] + } + }, + "id": "lens_rolled_up_data", + "metrics": [ + { + "field": "bytes", + "metrics": ["sum", "max"] + } + ], + "index_pattern": "lens_raw", + "timeout": "20s", + "page_size": 1000 + } + }, + "rollup-version": "8.0.0" + }, + "dynamic_templates": [ + { + "strings": { + "match_mapping_type": "string", + "mapping": { + "type": "keyword" + } + } + }, + { + "date_histograms": { + "path_match": "*.date_histogram.timestamp", + "mapping": { + "type": "date" + } + } + } + ], + "properties": { + "@timestamp": { + "properties": { + "date_histogram": { + "properties": { + "_count": { + "type": "long" + }, + "interval": { + "type": "keyword" + }, + "time_zone": { + "type": "keyword" + }, + "timestamp": { + "type": "date" + } + } + } + } + }, + "_rollup": { + "properties": { + "id": { + "type": "keyword" + }, + "version": { + "type": "long" + } + } + }, + "bytes": { + "properties": { + "max": { + "properties": { + "value": { + "type": "float" + } + } + }, + "sum": { + "properties": { + "value": { + "type": "float" + } + } + } + } + }, + "geo": { + "properties": { + "src": { + "properties": { + "terms": { + "properties": { + "_count": { + "type": "long" + }, + "value": { + "type": "keyword" + } + } + } + } + } + } + } + } + }, + "settings": { + "index": { + "number_of_shards": "1", + "number_of_replicas": "0" + } + } + } +} diff --git a/x-pack/test/plugin_functional/plugins/resolver_test/kibana.json b/x-pack/test/plugin_functional/plugins/resolver_test/kibana.json index c715a0aaa3b20..499983561e89d 100644 --- a/x-pack/test/plugin_functional/plugins/resolver_test/kibana.json +++ b/x-pack/test/plugin_functional/plugins/resolver_test/kibana.json @@ -2,8 +2,13 @@ "id": "resolver_test", "version": "1.0.0", "kibanaVersion": "kibana", - "configPath": ["xpack", "resolver_test"], - "requiredPlugins": ["embeddable"], + "configPath": ["xpack", "resolverTest"], + "requiredPlugins": [ + "securitySolution" + ], + "requiredBundles": [ + "kibanaReact" + ], "server": false, "ui": true } diff --git a/x-pack/test/plugin_functional/plugins/resolver_test/public/applications/resolver_test/index.tsx b/x-pack/test/plugin_functional/plugins/resolver_test/public/applications/resolver_test/index.tsx index 79665b6a393df..4afd71fd67a69 100644 --- a/x-pack/test/plugin_functional/plugins/resolver_test/public/applications/resolver_test/index.tsx +++ b/x-pack/test/plugin_functional/plugins/resolver_test/public/applications/resolver_test/index.tsx @@ -4,119 +4,95 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as React from 'react'; +import { Router } from 'react-router-dom'; + +import React from 'react'; import ReactDOM from 'react-dom'; -import { AppMountParameters } from 'kibana/public'; -import { I18nProvider } from '@kbn/i18n/react'; -import { IEmbeddable } from 'src/plugins/embeddable/public'; -import { useEffect } from 'react'; +import { AppMountParameters, CoreStart } from 'kibana/public'; +import { useMemo } from 'react'; import styled from 'styled-components'; +import { I18nProvider } from '@kbn/i18n/react'; +import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public'; +import { + DataAccessLayer, + ResolverPluginSetup, +} from '../../../../../../../plugins/security_solution/public/resolver/types'; /** * Render the Resolver Test app. Returns a cleanup function. */ export function renderApp( - { element }: AppMountParameters, - embeddable: Promise + coreStart: CoreStart, + parameters: AppMountParameters, + resolverPluginSetup: ResolverPluginSetup ) { /** * The application DOM node should take all available space. */ - element.style.display = 'flex'; - element.style.flexGrow = '1'; + parameters.element.style.display = 'flex'; + parameters.element.style.flexGrow = '1'; ReactDOM.render( - - - , - element + , + parameters.element ); return () => { - ReactDOM.unmountComponentAtNode(element); + ReactDOM.unmountComponentAtNode(parameters.element); }; } -const AppRoot = styled( - React.memo( - ({ - embeddable: embeddablePromise, - className, - }: { - /** - * A promise which resolves to the Resolver embeddable. - */ - embeddable: Promise; - /** - * A `className` string provided by `styled` - */ - className?: string; - }) => { - /** - * This state holds the reference to the embeddable, once resolved. - */ - const [embeddable, setEmbeddable] = React.useState(undefined); - /** - * This state holds the reference to the DOM node that will contain the embeddable. - */ - const [renderTarget, setRenderTarget] = React.useState(null); - - /** - * Keep component state with the Resolver embeddable. - * - * If the reference to the embeddablePromise changes, we ignore the stale promise. - */ - useEffect(() => { - /** - * A promise rejection function that will prevent a stale embeddable promise from being resolved - * as the current eembeddable. - * - * If the embeddablePromise itself changes before the old one is resolved, we cancel and restart this effect. - */ - let cleanUp; - - const cleanupPromise = new Promise((_resolve, reject) => { - cleanUp = reject; - }); - - /** - * Either set the embeddable in state, or cancel and restart this process. - */ - Promise.race([cleanupPromise, embeddablePromise]).then((value) => { - setEmbeddable(value); - }); +const AppRoot = React.memo( + ({ + coreStart, + parameters, + resolverPluginSetup, + }: { + coreStart: CoreStart; + parameters: AppMountParameters; + resolverPluginSetup: ResolverPluginSetup; + }) => { + const { + Provider, + storeFactory, + ResolverWithoutProviders, + mocks: { + dataAccessLayer: { noAncestorsTwoChildren }, + }, + } = resolverPluginSetup; + const dataAccessLayer: DataAccessLayer = useMemo( + () => noAncestorsTwoChildren().dataAccessLayer, + [noAncestorsTwoChildren] + ); - /** - * If `embeddablePromise` is changed, the cleanup function is run. - */ - return cleanUp; - }, [embeddablePromise]); + const store = useMemo(() => { + return storeFactory(dataAccessLayer); + }, [storeFactory, dataAccessLayer]); - /** - * Render the eembeddable into the DOM node. - */ - useEffect(() => { - if (embeddable && renderTarget) { - embeddable.render(renderTarget); - /** - * If the embeddable or DOM node changes then destroy the old embeddable. - */ - return () => { - embeddable.destroy(); - }; - } - }, [embeddable, renderTarget]); + return ( + + + + + + + + + + + + ); + } +); - return ( -
- ); - } - ) -)` +const Wrapper = styled.div` /** * Take all available space. */ diff --git a/x-pack/test/plugin_functional/plugins/resolver_test/public/plugin.ts b/x-pack/test/plugin_functional/plugins/resolver_test/public/plugin.ts index 853265ae6e5de..3da3044283556 100644 --- a/x-pack/test/plugin_functional/plugins/resolver_test/public/plugin.ts +++ b/x-pack/test/plugin_functional/plugins/resolver_test/public/plugin.ts @@ -4,16 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Plugin, CoreSetup } from 'kibana/public'; +import { Plugin, CoreSetup, AppMountParameters } from 'kibana/public'; import { i18n } from '@kbn/i18n'; -import { IEmbeddable, EmbeddableStart } from '../../../../../../src/plugins/embeddable/public'; +import { PluginSetup as SecuritySolutionPluginSetup } from '../../../../../plugins/security_solution/public'; export type ResolverTestPluginSetup = void; export type ResolverTestPluginStart = void; -export interface ResolverTestPluginSetupDependencies {} // eslint-disable-line @typescript-eslint/no-empty-interface -export interface ResolverTestPluginStartDependencies { - embeddable: EmbeddableStart; +export interface ResolverTestPluginSetupDependencies { + securitySolution: SecuritySolutionPluginSetup; } +export interface ResolverTestPluginStartDependencies {} // eslint-disable-line @typescript-eslint/no-empty-interface export class ResolverTestPlugin implements @@ -23,34 +23,24 @@ export class ResolverTestPlugin ResolverTestPluginSetupDependencies, ResolverTestPluginStartDependencies > { - public setup(core: CoreSetup) { + public setup( + core: CoreSetup, + setupDependencies: ResolverTestPluginSetupDependencies + ) { core.application.register({ - id: 'resolver_test', - title: i18n.translate('xpack.resolver_test.pluginTitle', { + id: 'resolverTest', + title: i18n.translate('xpack.resolverTest.pluginTitle', { defaultMessage: 'Resolver Test', }), - mount: async (_context, params) => { - let resolveEmbeddable: ( - value: IEmbeddable | undefined | PromiseLike | undefined - ) => void; + mount: async (params: AppMountParameters) => { + const startServices = await core.getStartServices(); + const [coreStart] = startServices; - const promise = new Promise((resolve) => { - resolveEmbeddable = resolve; - }); - - (async () => { - const [, { embeddable }] = await core.getStartServices(); - const factory = embeddable.getEmbeddableFactory('resolver'); - if (factory) { - resolveEmbeddable!(factory.create({ id: 'test basic render' })); - } - })(); - - const { renderApp } = await import('./applications/resolver_test'); - /** - * Pass a promise which resolves to the Resolver embeddable. - */ - return renderApp(params, promise); + const [{ renderApp }, resolverPluginSetup] = await Promise.all([ + import('./applications/resolver_test'), + setupDependencies.securitySolution.resolver(), + ]); + return renderApp(coreStart, params, resolverPluginSetup); }, }); }