From ab0cc8894a924dda18fc8664cf903fdf7a2d9920 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Mon, 6 Apr 2020 15:31:01 -0400 Subject: [PATCH 1/8] [Monitoring] Cluster state watch to Kibana alerting (#61685) * WIP * Add new alert with tests * Fix type issues, and disable new alerting for tests * Fix up the view all alerts view * Turn off for merging * Fix jest test Co-authored-by: Elastic Machine --- .../plugins/monitoring/common/constants.ts | 8 +- .../public/components/alerts/alerts.js | 44 +- .../public/components/alerts/status.test.tsx | 8 +- .../public/components/alerts/status.tsx | 2 +- .../cluster/overview/alerts_panel.js | 81 ++- .../monitoring/public/views/alerts/index.js | 30 +- x-pack/plugins/monitoring/common/constants.ts | 8 +- .../server/alerts/cluster_state.test.ts | 186 ++++++ .../monitoring/server/alerts/cluster_state.ts | 134 ++++ .../plugins/monitoring/server/alerts/enums.ts | 16 + .../server/alerts/license_expiration.test.ts | 572 +++++------------- .../server/alerts/license_expiration.ts | 127 ++-- .../monitoring/server/alerts/types.d.ts | 62 +- .../lib/alerts/cluster_state.lib.test.ts | 70 +++ .../server/lib/alerts/cluster_state.lib.ts | 88 +++ .../lib/alerts/fetch_cluster_state.test.ts | 39 ++ .../server/lib/alerts/fetch_cluster_state.ts | 53 ++ .../server/lib/alerts/fetch_clusters.test.ts | 46 +- .../server/lib/alerts/fetch_clusters.ts | 41 +- .../server/lib/alerts/fetch_licenses.test.ts | 67 +- .../server/lib/alerts/fetch_licenses.ts | 16 +- .../server/lib/alerts/fetch_status.test.ts | 122 ++++ .../server/lib/alerts/fetch_status.ts | 100 ++- .../lib/alerts/get_prepared_alert.test.ts | 163 +++++ .../server/lib/alerts/get_prepared_alert.ts | 87 +++ .../lib/alerts/license_expiration.lib.test.ts | 23 +- .../lib/alerts/license_expiration.lib.ts | 56 +- .../lib/cluster/get_clusters_from_request.js | 12 +- x-pack/plugins/monitoring/server/plugin.ts | 12 + .../server/routes/api/v1/alerts/alerts.js | 53 +- 30 files changed, 1570 insertions(+), 756 deletions(-) create mode 100644 x-pack/plugins/monitoring/server/alerts/cluster_state.test.ts create mode 100644 x-pack/plugins/monitoring/server/alerts/cluster_state.ts create mode 100644 x-pack/plugins/monitoring/server/alerts/enums.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/cluster_state.lib.test.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/cluster_state.lib.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_state.test.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_state.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/get_prepared_alert.test.ts create mode 100644 x-pack/plugins/monitoring/server/lib/alerts/get_prepared_alert.ts diff --git a/x-pack/legacy/plugins/monitoring/common/constants.ts b/x-pack/legacy/plugins/monitoring/common/constants.ts index 9a4030f3eb214..3a4c7b71dcd03 100644 --- a/x-pack/legacy/plugins/monitoring/common/constants.ts +++ b/x-pack/legacy/plugins/monitoring/common/constants.ts @@ -239,11 +239,15 @@ export const ALERT_TYPE_PREFIX = 'monitoring_'; * This is the alert type id for the license expiration alert */ export const ALERT_TYPE_LICENSE_EXPIRATION = `${ALERT_TYPE_PREFIX}alert_type_license_expiration`; +/** + * This is the alert type id for the cluster state alert + */ +export const ALERT_TYPE_CLUSTER_STATE = `${ALERT_TYPE_PREFIX}alert_type_cluster_state`; /** * A listing of all alert types */ -export const ALERT_TYPES = [ALERT_TYPE_LICENSE_EXPIRATION]; +export const ALERT_TYPES = [ALERT_TYPE_LICENSE_EXPIRATION, ALERT_TYPE_CLUSTER_STATE]; /** * Matches the id for the built-in in email action type @@ -254,7 +258,7 @@ export const ALERT_ACTION_TYPE_EMAIL = '.email'; /** * The number of alerts that have been migrated */ -export const NUMBER_OF_MIGRATED_ALERTS = 1; +export const NUMBER_OF_MIGRATED_ALERTS = 2; /** * The advanced settings config name for the email address diff --git a/x-pack/legacy/plugins/monitoring/public/components/alerts/alerts.js b/x-pack/legacy/plugins/monitoring/public/components/alerts/alerts.js index 11fcef73a4b97..95c1af5549198 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/alerts/alerts.js +++ b/x-pack/legacy/plugins/monitoring/public/components/alerts/alerts.js @@ -6,10 +6,15 @@ import React from 'react'; import chrome from '../../np_imports/ui/chrome'; -import { capitalize } from 'lodash'; +import { capitalize, get } from 'lodash'; import { formatDateTimeLocal } from '../../../common/formatting'; import { formatTimestampToDuration } from '../../../common'; -import { CALCULATE_DURATION_SINCE, EUI_SORT_DESCENDING } from '../../../common/constants'; +import { + CALCULATE_DURATION_SINCE, + EUI_SORT_DESCENDING, + ALERT_TYPE_LICENSE_EXPIRATION, + ALERT_TYPE_CLUSTER_STATE, +} from '../../../common/constants'; import { mapSeverity } from './map_severity'; import { FormattedAlert } from 'plugins/monitoring/components/alerts/formatted_alert'; import { EuiMonitoringTable } from 'plugins/monitoring/components/table'; @@ -21,6 +26,8 @@ const linkToCategories = { 'elasticsearch/indices': 'Elasticsearch Indices', 'kibana/instances': 'Kibana Instances', 'logstash/instances': 'Logstash Nodes', + [ALERT_TYPE_LICENSE_EXPIRATION]: 'License expiration', + [ALERT_TYPE_CLUSTER_STATE]: 'Cluster state', }; const getColumns = (kbnUrl, scope, timezone) => [ { @@ -94,19 +101,22 @@ const getColumns = (kbnUrl, scope, timezone) => [ }), field: 'message', sortable: true, - render: (message, alert) => ( - { - scope.$evalAsync(() => { - kbnUrl.changePath(target); - }); - }} - /> - ), + render: (_message, alert) => { + const message = get(alert, 'message.text', get(alert, 'message', '')); + return ( + { + scope.$evalAsync(() => { + kbnUrl.changePath(target); + }); + }} + /> + ); + }, }, { name: i18n.translate('xpack.monitoring.alerts.categoryColumnTitle', { @@ -148,8 +158,8 @@ const getColumns = (kbnUrl, scope, timezone) => [ export const Alerts = ({ alerts, angular, sorting, pagination, onTableChange }) => { const alertsFlattened = alerts.map(alert => ({ ...alert, - status: alert.metadata.severity, - category: alert.metadata.link, + status: get(alert, 'metadata.severity', get(alert, 'severity', 0)), + category: get(alert, 'metadata.link', get(alert, 'type', null)), })); const injector = chrome.dangerouslyGetActiveInjector(); diff --git a/x-pack/legacy/plugins/monitoring/public/components/alerts/status.test.tsx b/x-pack/legacy/plugins/monitoring/public/components/alerts/status.test.tsx index 258a5b68db372..d3cf4b463a2cc 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/alerts/status.test.tsx +++ b/x-pack/legacy/plugins/monitoring/public/components/alerts/status.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { kfetch } from 'ui/kfetch'; import { AlertsStatus, AlertsStatusProps } from './status'; -import { ALERT_TYPE_PREFIX } from '../../../common/constants'; +import { ALERT_TYPES } from '../../../common/constants'; import { getSetupModeState } from '../../lib/setup_mode'; import { mockUseEffects } from '../../jest.helpers'; @@ -63,11 +63,7 @@ describe('Status', () => { it('should render a success message if all alerts have been migrated and in setup mode', async () => { (kfetch as jest.Mock).mockReturnValue({ - data: [ - { - alertTypeId: ALERT_TYPE_PREFIX, - }, - ], + data: ALERT_TYPES.map(type => ({ alertTypeId: type })), }); (getSetupModeState as jest.Mock).mockReturnValue({ diff --git a/x-pack/legacy/plugins/monitoring/public/components/alerts/status.tsx b/x-pack/legacy/plugins/monitoring/public/components/alerts/status.tsx index 072a98b123452..5f5329bf7fff8 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/alerts/status.tsx +++ b/x-pack/legacy/plugins/monitoring/public/components/alerts/status.tsx @@ -142,7 +142,7 @@ export const AlertsStatus: React.FC = (props: AlertsStatusPro ); } - const allMigrated = kibanaAlerts.length === NUMBER_OF_MIGRATED_ALERTS; + const allMigrated = kibanaAlerts.length >= NUMBER_OF_MIGRATED_ALERTS; if (allMigrated) { if (setupModeEnabled) { return ( diff --git a/x-pack/legacy/plugins/monitoring/public/components/cluster/overview/alerts_panel.js b/x-pack/legacy/plugins/monitoring/public/components/cluster/overview/alerts_panel.js index 8455fb8cf3088..d87ff98e79be0 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/cluster/overview/alerts_panel.js +++ b/x-pack/legacy/plugins/monitoring/public/components/cluster/overview/alerts_panel.js @@ -6,14 +6,12 @@ import React, { Fragment } from 'react'; import moment from 'moment-timezone'; -import chrome from '../../../np_imports/ui/chrome'; import { FormattedAlert } from 'plugins/monitoring/components/alerts/formatted_alert'; import { mapSeverity } from 'plugins/monitoring/components/alerts/map_severity'; import { formatTimestampToDuration } from '../../../../common/format_timestamp_to_duration'; import { CALCULATE_DURATION_SINCE, KIBANA_ALERTING_ENABLED, - ALERT_TYPE_LICENSE_EXPIRATION, CALCULATE_DURATION_UNTIL, } from '../../../../common/constants'; import { formatDateTimeLocal } from '../../../../common/formatting'; @@ -31,6 +29,37 @@ import { EuiLink, } from '@elastic/eui'; +function replaceTokens(alert) { + if (!alert.message.tokens) { + return alert.message.text; + } + + let text = alert.message.text; + + for (const token of alert.message.tokens) { + if (token.type === 'time') { + text = text.replace( + token.startToken, + token.isRelative + ? formatTimestampToDuration(alert.expirationTime, CALCULATE_DURATION_UNTIL) + : moment.tz(alert.expirationTime, moment.tz.guess()).format('LLL z') + ); + } else if (token.type === 'link') { + const linkPart = new RegExp(`${token.startToken}(.+?)${token.endToken}`).exec(text); + // TODO: we assume this is at the end, which works for now but will not always work + const nonLinkText = text.replace(linkPart[0], ''); + text = ( + + {nonLinkText} + {linkPart[1]} + + ); + } + } + + return text; +} + export function AlertsPanel({ alerts, changeUrl }) { const goToAlerts = () => changeUrl('/alerts'); @@ -58,9 +87,6 @@ export function AlertsPanel({ alerts, changeUrl }) { severityIcon.iconType = 'check'; } - const injector = chrome.dangerouslyGetActiveInjector(); - const timezone = injector.get('config').get('dateFormat:tz'); - return ( @@ -96,14 +122,7 @@ export function AlertsPanel({ alerts, changeUrl }) { const alertsList = KIBANA_ALERTING_ENABLED ? alerts.map((alert, idx) => { const callOutProps = mapSeverity(alert.severity); - let message = alert.message - // scan message prefix and replace relative times - // \w: Matches any alphanumeric character from the basic Latin alphabet, including the underscore. Equivalent to [A-Za-z0-9_]. - .replace( - '#relative', - formatTimestampToDuration(alert.expirationTime, CALCULATE_DURATION_UNTIL) - ) - .replace('#absolute', moment.tz(alert.expirationTime, moment.tz.guess()).format('LLL z')); + const message = replaceTokens(alert); if (!alert.isFiring) { callOutProps.title = i18n.translate( @@ -118,22 +137,30 @@ export function AlertsPanel({ alerts, changeUrl }) { ); callOutProps.color = 'success'; callOutProps.iconType = 'check'; - } else { - if (alert.type === ALERT_TYPE_LICENSE_EXPIRATION) { - message = ( - - {message} -   - Please update your license - - ); - } } return ( - -

{message}

-
+ + +

{message}

+ +

+ +

+
+
+ +
); }) : alerts.map((item, index) => ( diff --git a/x-pack/legacy/plugins/monitoring/public/views/alerts/index.js b/x-pack/legacy/plugins/monitoring/public/views/alerts/index.js index 7c065a78a8af9..62cc985887e9f 100644 --- a/x-pack/legacy/plugins/monitoring/public/views/alerts/index.js +++ b/x-pack/legacy/plugins/monitoring/public/views/alerts/index.js @@ -18,25 +18,37 @@ import { Alerts } from '../../components/alerts'; import { MonitoringViewBaseEuiTableController } from '../base_eui_table_controller'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiLink } from '@elastic/eui'; -import { CODE_PATH_ALERTS } from '../../../common/constants'; +import { CODE_PATH_ALERTS, KIBANA_ALERTING_ENABLED } from '../../../common/constants'; function getPageData($injector) { const globalState = $injector.get('globalState'); const $http = $injector.get('$http'); const Private = $injector.get('Private'); - const url = `../api/monitoring/v1/clusters/${globalState.cluster_uuid}/legacy_alerts`; + const url = KIBANA_ALERTING_ENABLED + ? `../api/monitoring/v1/alert_status` + : `../api/monitoring/v1/clusters/${globalState.cluster_uuid}/legacy_alerts`; const timeBounds = timefilter.getBounds(); + const data = { + timeRange: { + min: timeBounds.min.toISOString(), + max: timeBounds.max.toISOString(), + }, + }; + + if (!KIBANA_ALERTING_ENABLED) { + data.ccs = globalState.ccs; + } return $http - .post(url, { - ccs: globalState.ccs, - timeRange: { - min: timeBounds.min.toISOString(), - max: timeBounds.max.toISOString(), - }, + .post(url, data) + .then(response => { + const result = get(response, 'data', []); + if (KIBANA_ALERTING_ENABLED) { + return result.alerts; + } + return result; }) - .then(response => get(response, 'data', [])) .catch(err => { const ajaxErrorHandlers = Private(ajaxErrorHandlersProvider); return ajaxErrorHandlers(err); diff --git a/x-pack/plugins/monitoring/common/constants.ts b/x-pack/plugins/monitoring/common/constants.ts index 9a4030f3eb214..3a4c7b71dcd03 100644 --- a/x-pack/plugins/monitoring/common/constants.ts +++ b/x-pack/plugins/monitoring/common/constants.ts @@ -239,11 +239,15 @@ export const ALERT_TYPE_PREFIX = 'monitoring_'; * This is the alert type id for the license expiration alert */ export const ALERT_TYPE_LICENSE_EXPIRATION = `${ALERT_TYPE_PREFIX}alert_type_license_expiration`; +/** + * This is the alert type id for the cluster state alert + */ +export const ALERT_TYPE_CLUSTER_STATE = `${ALERT_TYPE_PREFIX}alert_type_cluster_state`; /** * A listing of all alert types */ -export const ALERT_TYPES = [ALERT_TYPE_LICENSE_EXPIRATION]; +export const ALERT_TYPES = [ALERT_TYPE_LICENSE_EXPIRATION, ALERT_TYPE_CLUSTER_STATE]; /** * Matches the id for the built-in in email action type @@ -254,7 +258,7 @@ export const ALERT_ACTION_TYPE_EMAIL = '.email'; /** * The number of alerts that have been migrated */ -export const NUMBER_OF_MIGRATED_ALERTS = 1; +export const NUMBER_OF_MIGRATED_ALERTS = 2; /** * The advanced settings config name for the email address diff --git a/x-pack/plugins/monitoring/server/alerts/cluster_state.test.ts b/x-pack/plugins/monitoring/server/alerts/cluster_state.test.ts new file mode 100644 index 0000000000000..6a9ca88437347 --- /dev/null +++ b/x-pack/plugins/monitoring/server/alerts/cluster_state.test.ts @@ -0,0 +1,186 @@ +/* + * 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 { Logger } from 'src/core/server'; +import { savedObjectsClientMock } from 'src/core/server/mocks'; +import { getClusterState } from './cluster_state'; +import { AlertServices } from '../../../alerting/server'; +import { ALERT_TYPE_CLUSTER_STATE } from '../../common/constants'; +import { AlertCommonParams, AlertCommonState, AlertClusterStatePerClusterState } from './types'; +import { getPreparedAlert } from '../lib/alerts/get_prepared_alert'; +import { executeActions } from '../lib/alerts/cluster_state.lib'; +import { AlertClusterStateState } from './enums'; + +jest.mock('../lib/alerts/cluster_state.lib', () => ({ + executeActions: jest.fn(), + getUiMessage: jest.fn(), +})); + +jest.mock('../lib/alerts/get_prepared_alert', () => ({ + getPreparedAlert: jest.fn(() => { + return { + emailAddress: 'foo@foo.com', + }; + }), +})); + +interface MockServices { + callCluster: jest.Mock; + alertInstanceFactory: jest.Mock; + savedObjectsClient: jest.Mock; +} + +describe('getClusterState', () => { + const services: MockServices | AlertServices = { + callCluster: jest.fn(), + alertInstanceFactory: jest.fn(), + savedObjectsClient: savedObjectsClientMock.create(), + }; + + const params: AlertCommonParams = { + dateFormat: 'YYYY', + timezone: 'UTC', + }; + + const emailAddress = 'foo@foo.com'; + const clusterUuid = 'kdksdfj434'; + const clusterName = 'monitoring_test'; + const cluster = { clusterUuid, clusterName }; + + async function setupAlert( + previousState: AlertClusterStateState, + newState: AlertClusterStateState + ): Promise { + const logger: Logger = { + warn: jest.fn(), + log: jest.fn(), + debug: jest.fn(), + trace: jest.fn(), + error: jest.fn(), + fatal: jest.fn(), + info: jest.fn(), + get: jest.fn(), + }; + const getLogger = (): Logger => logger; + const ccrEnabled = false; + (getPreparedAlert as jest.Mock).mockImplementation(() => ({ + emailAddress, + data: [ + { + state: newState, + clusterUuid, + }, + ], + clusters: [cluster], + })); + + const alert = getClusterState(null as any, null as any, getLogger, ccrEnabled); + const state: AlertCommonState = { + [clusterUuid]: { + state: previousState, + ui: { + isFiring: false, + severity: 0, + message: null, + resolvedMS: 0, + lastCheckedMS: 0, + triggeredMS: 0, + }, + } as AlertClusterStatePerClusterState, + }; + + return (await alert.executor({ services, params, state } as any)) as AlertCommonState; + } + + afterEach(() => { + (executeActions as jest.Mock).mockClear(); + }); + + it('should configure the alert properly', () => { + const alert = getClusterState(null as any, null as any, jest.fn(), false); + expect(alert.id).toBe(ALERT_TYPE_CLUSTER_STATE); + expect(alert.actionGroups).toEqual([{ id: 'default', name: 'Default' }]); + }); + + it('should alert if green -> yellow', async () => { + const result = await setupAlert(AlertClusterStateState.Green, AlertClusterStateState.Yellow); + expect(executeActions).toHaveBeenCalledWith( + undefined, + cluster, + AlertClusterStateState.Yellow, + emailAddress + ); + const clusterResult = result[clusterUuid] as AlertClusterStatePerClusterState; + expect(clusterResult.state).toBe(AlertClusterStateState.Yellow); + expect(clusterResult.ui.isFiring).toBe(true); + expect(clusterResult.ui.resolvedMS).toBe(0); + }); + + it('should alert if yellow -> green', async () => { + const result = await setupAlert(AlertClusterStateState.Yellow, AlertClusterStateState.Green); + expect(executeActions).toHaveBeenCalledWith( + undefined, + cluster, + AlertClusterStateState.Green, + emailAddress, + true + ); + const clusterResult = result[clusterUuid] as AlertClusterStatePerClusterState; + expect(clusterResult.state).toBe(AlertClusterStateState.Green); + expect(clusterResult.ui.resolvedMS).toBeGreaterThan(0); + }); + + it('should alert if green -> red', async () => { + const result = await setupAlert(AlertClusterStateState.Green, AlertClusterStateState.Red); + expect(executeActions).toHaveBeenCalledWith( + undefined, + cluster, + AlertClusterStateState.Red, + emailAddress + ); + const clusterResult = result[clusterUuid] as AlertClusterStatePerClusterState; + expect(clusterResult.state).toBe(AlertClusterStateState.Red); + expect(clusterResult.ui.isFiring).toBe(true); + expect(clusterResult.ui.resolvedMS).toBe(0); + }); + + it('should alert if red -> green', async () => { + const result = await setupAlert(AlertClusterStateState.Red, AlertClusterStateState.Green); + expect(executeActions).toHaveBeenCalledWith( + undefined, + cluster, + AlertClusterStateState.Green, + emailAddress, + true + ); + const clusterResult = result[clusterUuid] as AlertClusterStatePerClusterState; + expect(clusterResult.state).toBe(AlertClusterStateState.Green); + expect(clusterResult.ui.resolvedMS).toBeGreaterThan(0); + }); + + it('should not alert if red -> yellow', async () => { + const result = await setupAlert(AlertClusterStateState.Red, AlertClusterStateState.Yellow); + expect(executeActions).not.toHaveBeenCalled(); + const clusterResult = result[clusterUuid] as AlertClusterStatePerClusterState; + expect(clusterResult.state).toBe(AlertClusterStateState.Red); + expect(clusterResult.ui.resolvedMS).toBe(0); + }); + + it('should not alert if yellow -> red', async () => { + const result = await setupAlert(AlertClusterStateState.Yellow, AlertClusterStateState.Red); + expect(executeActions).not.toHaveBeenCalled(); + const clusterResult = result[clusterUuid] as AlertClusterStatePerClusterState; + expect(clusterResult.state).toBe(AlertClusterStateState.Yellow); + expect(clusterResult.ui.resolvedMS).toBe(0); + }); + + it('should not alert if green -> green', async () => { + const result = await setupAlert(AlertClusterStateState.Green, AlertClusterStateState.Green); + expect(executeActions).not.toHaveBeenCalled(); + const clusterResult = result[clusterUuid] as AlertClusterStatePerClusterState; + expect(clusterResult.state).toBe(AlertClusterStateState.Green); + expect(clusterResult.ui.resolvedMS).toBe(0); + }); +}); diff --git a/x-pack/plugins/monitoring/server/alerts/cluster_state.ts b/x-pack/plugins/monitoring/server/alerts/cluster_state.ts new file mode 100644 index 0000000000000..9a5805b8af7ce --- /dev/null +++ b/x-pack/plugins/monitoring/server/alerts/cluster_state.ts @@ -0,0 +1,134 @@ +/* + * 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 moment from 'moment-timezone'; +import { i18n } from '@kbn/i18n'; +import { Logger, ICustomClusterClient, UiSettingsServiceStart } from 'src/core/server'; +import { ALERT_TYPE_CLUSTER_STATE } from '../../common/constants'; +import { AlertType } from '../../../alerting/server'; +import { executeActions, getUiMessage } from '../lib/alerts/cluster_state.lib'; +import { + AlertCommonExecutorOptions, + AlertCommonState, + AlertClusterStatePerClusterState, + AlertCommonCluster, +} from './types'; +import { AlertClusterStateState } from './enums'; +import { getPreparedAlert } from '../lib/alerts/get_prepared_alert'; +import { fetchClusterState } from '../lib/alerts/fetch_cluster_state'; + +export const getClusterState = ( + getUiSettingsService: () => Promise, + monitoringCluster: ICustomClusterClient, + getLogger: (...scopes: string[]) => Logger, + ccsEnabled: boolean +): AlertType => { + const logger = getLogger(ALERT_TYPE_CLUSTER_STATE); + return { + id: ALERT_TYPE_CLUSTER_STATE, + name: 'Monitoring Alert - Cluster Status', + actionGroups: [ + { + id: 'default', + name: i18n.translate('xpack.monitoring.alerts.clusterState.actionGroups.default', { + defaultMessage: 'Default', + }), + }, + ], + defaultActionGroupId: 'default', + async executor({ + services, + params, + state, + }: AlertCommonExecutorOptions): Promise { + logger.debug( + `Firing alert with params: ${JSON.stringify(params)} and state: ${JSON.stringify(state)}` + ); + + const preparedAlert = await getPreparedAlert( + ALERT_TYPE_CLUSTER_STATE, + getUiSettingsService, + monitoringCluster, + logger, + ccsEnabled, + services, + fetchClusterState + ); + + if (!preparedAlert) { + return state; + } + + const { emailAddress, data: states, clusters } = preparedAlert; + + const result: AlertCommonState = { ...state }; + const defaultAlertState: AlertClusterStatePerClusterState = { + state: AlertClusterStateState.Green, + ui: { + isFiring: false, + message: null, + severity: 0, + resolvedMS: 0, + triggeredMS: 0, + lastCheckedMS: 0, + }, + }; + + for (const clusterState of states) { + const alertState: AlertClusterStatePerClusterState = + (state[clusterState.clusterUuid] as AlertClusterStatePerClusterState) || + defaultAlertState; + const cluster = clusters.find( + (c: AlertCommonCluster) => c.clusterUuid === clusterState.clusterUuid + ); + if (!cluster) { + logger.warn(`Unable to find cluster for clusterUuid='${clusterState.clusterUuid}'`); + continue; + } + const isNonGreen = clusterState.state !== AlertClusterStateState.Green; + const severity = clusterState.state === AlertClusterStateState.Red ? 2100 : 1100; + + const ui = alertState.ui; + let triggered = ui.triggeredMS; + let resolved = ui.resolvedMS; + let message = ui.message || {}; + let lastState = alertState.state; + const instance = services.alertInstanceFactory(ALERT_TYPE_CLUSTER_STATE); + + if (isNonGreen) { + if (lastState === AlertClusterStateState.Green) { + logger.debug(`Cluster state changed from green to ${clusterState.state}`); + executeActions(instance, cluster, clusterState.state, emailAddress); + lastState = clusterState.state; + triggered = moment().valueOf(); + } + message = getUiMessage(clusterState.state); + resolved = 0; + } else if (!isNonGreen && lastState !== AlertClusterStateState.Green) { + logger.debug(`Cluster state changed from ${lastState} to green`); + executeActions(instance, cluster, clusterState.state, emailAddress, true); + lastState = clusterState.state; + message = getUiMessage(clusterState.state, true); + resolved = moment().valueOf(); + } + + result[clusterState.clusterUuid] = { + state: lastState, + ui: { + message, + isFiring: isNonGreen, + severity, + resolvedMS: resolved, + triggeredMS: triggered, + lastCheckedMS: moment().valueOf(), + }, + } as AlertClusterStatePerClusterState; + } + + return result; + }, + }; +}; diff --git a/x-pack/plugins/monitoring/server/alerts/enums.ts b/x-pack/plugins/monitoring/server/alerts/enums.ts new file mode 100644 index 0000000000000..ccff588743af1 --- /dev/null +++ b/x-pack/plugins/monitoring/server/alerts/enums.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export enum AlertClusterStateState { + Green = 'green', + Red = 'red', + Yellow = 'yellow', +} + +export enum AlertCommonPerClusterMessageTokenType { + Time = 'time', + Link = 'link', +} diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration.test.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration.test.ts index 0773af6e7f070..92047e300bc1f 100644 --- a/x-pack/plugins/monitoring/server/alerts/license_expiration.test.ts +++ b/x-pack/plugins/monitoring/server/alerts/license_expiration.test.ts @@ -6,42 +6,31 @@ import moment from 'moment-timezone'; import { getLicenseExpiration } from './license_expiration'; -import { - ALERT_TYPE_LICENSE_EXPIRATION, - MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS, -} from '../../common/constants'; +import { ALERT_TYPE_LICENSE_EXPIRATION } from '../../common/constants'; import { Logger } from 'src/core/server'; -import { AlertServices, AlertInstance } from '../../../alerting/server'; +import { AlertServices } from '../../../alerting/server'; import { savedObjectsClientMock } from 'src/core/server/mocks'; import { - AlertState, - AlertClusterState, - AlertParams, - LicenseExpirationAlertExecutorOptions, + AlertCommonParams, + AlertCommonState, + AlertLicensePerClusterState, + AlertLicense, } from './types'; -import { SavedObject, SavedObjectAttributes } from 'src/core/server'; -import { SavedObjectsClientContract } from 'src/core/server'; - -function fillLicense(license: any, clusterUuid?: string) { - return { - hits: { - hits: [ - { - _source: { - license, - cluster_uuid: clusterUuid, - }, - }, - ], - }, - }; -} - -const clusterUuid = 'a4545jhjb'; -const params: AlertParams = { - dateFormat: 'YYYY', - timezone: 'UTC', -}; +import { executeActions } from '../lib/alerts/license_expiration.lib'; +import { PreparedAlert, getPreparedAlert } from '../lib/alerts/get_prepared_alert'; + +jest.mock('../lib/alerts/license_expiration.lib', () => ({ + executeActions: jest.fn(), + getUiMessage: jest.fn(), +})); + +jest.mock('../lib/alerts/get_prepared_alert', () => ({ + getPreparedAlert: jest.fn(() => { + return { + emailAddress: 'foo@foo.com', + }; + }), +})); interface MockServices { callCluster: jest.Mock; @@ -49,428 +38,169 @@ interface MockServices { savedObjectsClient: jest.Mock; } -const alertExecutorOptions: LicenseExpirationAlertExecutorOptions = { - alertId: '', - startedAt: new Date(), - services: { - callCluster: (path: string, opts: any) => new Promise(resolve => resolve()), - alertInstanceFactory: (id: string) => new AlertInstance(), - savedObjectsClient: {} as jest.Mocked, - }, - params: {}, - state: {}, - spaceId: '', - name: '', - tags: [], - previousStartedAt: null, - createdBy: null, - updatedBy: null, -}; - describe('getLicenseExpiration', () => { - const emailAddress = 'foo@foo.com'; - const getUiSettingsService: any = () => ({ - asScopedToClient: (): any => ({ - get: () => new Promise(resolve => resolve(emailAddress)), - }), - }); - const monitoringCluster: any = null; - const logger: Logger = { - warn: jest.fn(), - log: jest.fn(), - debug: jest.fn(), - trace: jest.fn(), - error: jest.fn(), - fatal: jest.fn(), - info: jest.fn(), - get: jest.fn(), + const services: MockServices | AlertServices = { + callCluster: jest.fn(), + alertInstanceFactory: jest.fn(), + savedObjectsClient: savedObjectsClientMock.create(), }; - const getLogger = (): Logger => logger; - const ccrEnabled = false; - afterEach(() => { - (logger.warn as jest.Mock).mockClear(); - }); - - it('should have the right id and actionGroups', () => { - const alert = getLicenseExpiration( - getUiSettingsService, - monitoringCluster, - getLogger, - ccrEnabled - ); - expect(alert.id).toBe(ALERT_TYPE_LICENSE_EXPIRATION); - expect(alert.actionGroups).toEqual([{ id: 'default', name: 'Default' }]); - }); + const params: AlertCommonParams = { + dateFormat: 'YYYY', + timezone: 'UTC', + }; - it('should return the state if no license is provided', async () => { - const alert = getLicenseExpiration( - getUiSettingsService, - monitoringCluster, - getLogger, - ccrEnabled - ); + const emailAddress = 'foo@foo.com'; + const clusterUuid = 'kdksdfj434'; + const clusterName = 'monitoring_test'; + const dateFormat = 'YYYY-MM-DD'; + const cluster = { clusterUuid, clusterName }; + const defaultUiState = { + isFiring: false, + severity: 0, + message: null, + resolvedMS: 0, + lastCheckedMS: 0, + triggeredMS: 0, + }; - const services: MockServices | AlertServices = { - callCluster: jest.fn(), - alertInstanceFactory: jest.fn(), - savedObjectsClient: savedObjectsClientMock.create(), + async function setupAlert( + license: AlertLicense | null, + expiredCheckDateMS: number, + preparedAlertResponse: PreparedAlert | null | undefined = undefined + ): Promise { + const logger: Logger = { + warn: jest.fn(), + log: jest.fn(), + debug: jest.fn(), + trace: jest.fn(), + error: jest.fn(), + fatal: jest.fn(), + info: jest.fn(), + get: jest.fn(), }; - const state = { foo: 1 }; - - const result = await alert.executor({ - ...alertExecutorOptions, - services, - params, - state, - }); - - expect(result).toEqual(state); - }); + const getLogger = (): Logger => logger; + const ccrEnabled = false; + (getPreparedAlert as jest.Mock).mockImplementation(() => { + if (preparedAlertResponse !== undefined) { + return preparedAlertResponse; + } - it('should log a warning if no email is provided', async () => { - const customGetUiSettingsService: any = () => ({ - asScopedToClient: () => ({ - get: () => null, - }), + return { + emailAddress, + data: [license], + clusters: [cluster], + dateFormat, + }; }); - const alert = getLicenseExpiration( - customGetUiSettingsService, - monitoringCluster, - getLogger, - ccrEnabled - ); - const services = { - callCluster: jest.fn( - (method: string, { filterPath }): Promise => { - return new Promise(resolve => { - if (filterPath.includes('hits.hits._source.license.*')) { - resolve( - fillLicense({ - status: 'good', - type: 'basic', - expiry_date_in_millis: moment() - .add(7, 'days') - .valueOf(), - }) - ); - } - resolve({}); - }); - } - ), - alertInstanceFactory: jest.fn(), - savedObjectsClient: savedObjectsClientMock.create(), + const alert = getLicenseExpiration(null as any, null as any, getLogger, ccrEnabled); + const state: AlertCommonState = { + [clusterUuid]: { + expiredCheckDateMS, + ui: { ...defaultUiState }, + } as AlertLicensePerClusterState, }; - const state = {}; + return (await alert.executor({ services, params, state } as any)) as AlertCommonState; + } - await alert.executor({ - ...alertExecutorOptions, - services, - params, - state, - }); - - expect((logger.warn as jest.Mock).mock.calls.length).toBe(1); - expect(logger.warn).toHaveBeenCalledWith( - `Unable to send email for ${ALERT_TYPE_LICENSE_EXPIRATION} because there is no email configured.` - ); + afterEach(() => { + (executeActions as jest.Mock).mockClear(); + (getPreparedAlert as jest.Mock).mockClear(); }); - it('should fire actions if going to expire', async () => { - const scheduleActions = jest.fn(); - const alertInstanceFactory = jest.fn( - (id: string): AlertInstance => { - const instance = new AlertInstance(); - instance.scheduleActions = scheduleActions; - return instance; - } - ); + it('should have the right id and actionGroups', () => { + const alert = getLicenseExpiration(null as any, null as any, jest.fn(), false); + expect(alert.id).toBe(ALERT_TYPE_LICENSE_EXPIRATION); + expect(alert.actionGroups).toEqual([{ id: 'default', name: 'Default' }]); + }); - const alert = getLicenseExpiration( - getUiSettingsService, - monitoringCluster, - getLogger, - ccrEnabled - ); + it('should return the state if no license is provided', async () => { + const result = await setupAlert(null, 0, null); + expect(result[clusterUuid].ui).toEqual(defaultUiState); + }); - const savedObjectsClient = savedObjectsClientMock.create(); - savedObjectsClient.get.mockReturnValue( - new Promise(resolve => { - const savedObject: SavedObject = { - id: '', - type: '', - references: [], - attributes: { - [MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS]: emailAddress, - }, - }; - resolve(savedObject); - }) - ); - const services = { - callCluster: jest.fn( - (method: string, { filterPath }): Promise => { - return new Promise(resolve => { - if (filterPath.includes('hits.hits._source.license.*')) { - resolve( - fillLicense( - { - status: 'active', - type: 'gold', - expiry_date_in_millis: moment() - .add(7, 'days') - .valueOf(), - }, - clusterUuid - ) - ); - } - resolve({}); - }); - } - ), - alertInstanceFactory, - savedObjectsClient, + it('should fire actions if going to expire', async () => { + const expiryDateMS = moment() + .add(7, 'days') + .valueOf(); + const license = { + status: 'active', + type: 'gold', + expiryDateMS, + clusterUuid, }; - - const state = {}; - - const result: AlertState = (await alert.executor({ - ...alertExecutorOptions, - services, - params, - state, - })) as AlertState; - - const newState: AlertClusterState = result[clusterUuid] as AlertClusterState; - + const result = await setupAlert(license, 0); + const newState = result[clusterUuid] as AlertLicensePerClusterState; expect(newState.expiredCheckDateMS > 0).toBe(true); - expect(scheduleActions.mock.calls.length).toBe(1); - expect(scheduleActions.mock.calls[0][1].subject).toBe( - 'NEW X-Pack Monitoring: License Expiration' + expect(executeActions).toHaveBeenCalledWith( + undefined, + cluster, + moment.utc(expiryDateMS), + dateFormat, + emailAddress ); - expect(scheduleActions.mock.calls[0][1].to).toBe(emailAddress); }); it('should fire actions if the user fixed their license', async () => { - const scheduleActions = jest.fn(); - const alertInstanceFactory = jest.fn( - (id: string): AlertInstance => { - const instance = new AlertInstance(); - instance.scheduleActions = scheduleActions; - return instance; - } - ); - const alert = getLicenseExpiration( - getUiSettingsService, - monitoringCluster, - getLogger, - ccrEnabled - ); - - const savedObjectsClient = savedObjectsClientMock.create(); - savedObjectsClient.get.mockReturnValue( - new Promise(resolve => { - const savedObject: SavedObject = { - id: '', - type: '', - references: [], - attributes: { - [MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS]: emailAddress, - }, - }; - resolve(savedObject); - }) - ); - const services = { - callCluster: jest.fn( - (method: string, { filterPath }): Promise => { - return new Promise(resolve => { - if (filterPath.includes('hits.hits._source.license.*')) { - resolve( - fillLicense( - { - status: 'active', - type: 'gold', - expiry_date_in_millis: moment() - .add(120, 'days') - .valueOf(), - }, - clusterUuid - ) - ); - } - resolve({}); - }); - } - ), - alertInstanceFactory, - savedObjectsClient, - }; - - const state: AlertState = { - [clusterUuid]: { - expiredCheckDateMS: moment() - .subtract(1, 'day') - .valueOf(), - ui: { isFiring: true, severity: 0, message: null, resolvedMS: 0, expirationTime: 0 }, - }, + const expiryDateMS = moment() + .add(365, 'days') + .valueOf(); + const license = { + status: 'active', + type: 'gold', + expiryDateMS, + clusterUuid, }; - - const result: AlertState = (await alert.executor({ - ...alertExecutorOptions, - services, - params, - state, - })) as AlertState; - - const newState: AlertClusterState = result[clusterUuid] as AlertClusterState; + const result = await setupAlert(license, 100); + const newState = result[clusterUuid] as AlertLicensePerClusterState; expect(newState.expiredCheckDateMS).toBe(0); - expect(scheduleActions.mock.calls.length).toBe(1); - expect(scheduleActions.mock.calls[0][1].subject).toBe( - 'RESOLVED X-Pack Monitoring: License Expiration' + expect(executeActions).toHaveBeenCalledWith( + undefined, + cluster, + moment.utc(expiryDateMS), + dateFormat, + emailAddress, + true ); - expect(scheduleActions.mock.calls[0][1].to).toBe(emailAddress); }); it('should not fire actions for trial license that expire in more than 14 days', async () => { - const scheduleActions = jest.fn(); - const alertInstanceFactory = jest.fn( - (id: string): AlertInstance => { - const instance = new AlertInstance(); - instance.scheduleActions = scheduleActions; - return instance; - } - ); - const alert = getLicenseExpiration( - getUiSettingsService, - monitoringCluster, - getLogger, - ccrEnabled - ); - - const savedObjectsClient = savedObjectsClientMock.create(); - savedObjectsClient.get.mockReturnValue( - new Promise(resolve => { - const savedObject: SavedObject = { - id: '', - type: '', - references: [], - attributes: { - [MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS]: emailAddress, - }, - }; - resolve(savedObject); - }) - ); - const services = { - callCluster: jest.fn( - (method: string, { filterPath }): Promise => { - return new Promise(resolve => { - if (filterPath.includes('hits.hits._source.license.*')) { - resolve( - fillLicense( - { - status: 'active', - type: 'trial', - expiry_date_in_millis: moment() - .add(15, 'days') - .valueOf(), - }, - clusterUuid - ) - ); - } - resolve({}); - }); - } - ), - alertInstanceFactory, - savedObjectsClient, + const expiryDateMS = moment() + .add(20, 'days') + .valueOf(); + const license = { + status: 'active', + type: 'trial', + expiryDateMS, + clusterUuid, }; - - const state = {}; - const result: AlertState = (await alert.executor({ - ...alertExecutorOptions, - services, - params, - state, - })) as AlertState; - - const newState: AlertClusterState = result[clusterUuid] as AlertClusterState; - expect(newState.expiredCheckDateMS).toBe(undefined); - expect(scheduleActions).not.toHaveBeenCalled(); + const result = await setupAlert(license, 0); + const newState = result[clusterUuid] as AlertLicensePerClusterState; + expect(newState.expiredCheckDateMS).toBe(0); + expect(executeActions).not.toHaveBeenCalled(); }); it('should fire actions for trial license that in 14 days or less', async () => { - const scheduleActions = jest.fn(); - const alertInstanceFactory = jest.fn( - (id: string): AlertInstance => { - const instance = new AlertInstance(); - instance.scheduleActions = scheduleActions; - return instance; - } - ); - const alert = getLicenseExpiration( - getUiSettingsService, - monitoringCluster, - getLogger, - ccrEnabled - ); - - const savedObjectsClient = savedObjectsClientMock.create(); - savedObjectsClient.get.mockReturnValue( - new Promise(resolve => { - const savedObject: SavedObject = { - id: '', - type: '', - references: [], - attributes: { - [MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS]: emailAddress, - }, - }; - resolve(savedObject); - }) - ); - const services = { - callCluster: jest.fn( - (method: string, { filterPath }): Promise => { - return new Promise(resolve => { - if (filterPath.includes('hits.hits._source.license.*')) { - resolve( - fillLicense( - { - status: 'active', - type: 'trial', - expiry_date_in_millis: moment() - .add(13, 'days') - .valueOf(), - }, - clusterUuid - ) - ); - } - resolve({}); - }); - } - ), - alertInstanceFactory, - savedObjectsClient, + const expiryDateMS = moment() + .add(7, 'days') + .valueOf(); + const license = { + status: 'active', + type: 'trial', + expiryDateMS, + clusterUuid, }; - - const state = {}; - const result: AlertState = (await alert.executor({ - ...alertExecutorOptions, - services, - params, - state, - })) as AlertState; - - const newState: AlertClusterState = result[clusterUuid] as AlertClusterState; + const result = await setupAlert(license, 0); + const newState = result[clusterUuid] as AlertLicensePerClusterState; expect(newState.expiredCheckDateMS > 0).toBe(true); - expect(scheduleActions.mock.calls.length).toBe(1); + expect(executeActions).toHaveBeenCalledWith( + undefined, + cluster, + moment.utc(expiryDateMS), + dateFormat, + emailAddress + ); }); }); diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration.ts index 93397ff3641ae..2e5356150086b 100644 --- a/x-pack/plugins/monitoring/server/alerts/license_expiration.ts +++ b/x-pack/plugins/monitoring/server/alerts/license_expiration.ts @@ -5,24 +5,20 @@ */ import moment from 'moment-timezone'; -import { get } from 'lodash'; import { Logger, ICustomClusterClient, UiSettingsServiceStart } from 'src/core/server'; import { i18n } from '@kbn/i18n'; -import { ALERT_TYPE_LICENSE_EXPIRATION, INDEX_PATTERN_ELASTICSEARCH } from '../../common/constants'; +import { ALERT_TYPE_LICENSE_EXPIRATION } from '../../common/constants'; import { AlertType } from '../../../../plugins/alerting/server'; import { fetchLicenses } from '../lib/alerts/fetch_licenses'; -import { fetchDefaultEmailAddress } from '../lib/alerts/fetch_default_email_address'; -import { fetchClusters } from '../lib/alerts/fetch_clusters'; -import { fetchAvailableCcs } from '../lib/alerts/fetch_available_ccs'; import { - AlertLicense, - AlertState, - AlertClusterState, - AlertClusterUiState, - LicenseExpirationAlertExecutorOptions, + AlertCommonState, + AlertLicensePerClusterState, + AlertCommonExecutorOptions, + AlertCommonCluster, + AlertLicensePerClusterUiState, } from './types'; -import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; import { executeActions, getUiMessage } from '../lib/alerts/license_expiration.lib'; +import { getPreparedAlert } from '../lib/alerts/get_prepared_alert'; const EXPIRES_DAYS = [60, 30, 14, 7]; @@ -32,14 +28,6 @@ export const getLicenseExpiration = ( getLogger: (...scopes: string[]) => Logger, ccsEnabled: boolean ): AlertType => { - async function getCallCluster(services: any): Promise { - if (!monitoringCluster) { - return services.callCluster; - } - - return monitoringCluster.callAsInternalUser; - } - const logger = getLogger(ALERT_TYPE_LICENSE_EXPIRATION); return { id: ALERT_TYPE_LICENSE_EXPIRATION, @@ -53,54 +41,50 @@ export const getLicenseExpiration = ( }, ], defaultActionGroupId: 'default', - async executor({ - services, - params, - state, - }: LicenseExpirationAlertExecutorOptions): Promise { + async executor({ services, params, state }: AlertCommonExecutorOptions): Promise { logger.debug( `Firing alert with params: ${JSON.stringify(params)} and state: ${JSON.stringify(state)}` ); - const callCluster = await getCallCluster(services); - - // Support CCS use cases by querying to find available remote clusters - // and then adding those to the index pattern we are searching against - let esIndexPattern = INDEX_PATTERN_ELASTICSEARCH; - if (ccsEnabled) { - const availableCcs = await fetchAvailableCcs(callCluster); - if (availableCcs.length > 0) { - esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs); - } - } - - const clusters = await fetchClusters(callCluster, esIndexPattern); + const preparedAlert = await getPreparedAlert( + ALERT_TYPE_LICENSE_EXPIRATION, + getUiSettingsService, + monitoringCluster, + logger, + ccsEnabled, + services, + fetchLicenses + ); - // Fetch licensing information from cluster_stats documents - const licenses: AlertLicense[] = await fetchLicenses(callCluster, clusters, esIndexPattern); - if (licenses.length === 0) { - logger.warn(`No license found for ${ALERT_TYPE_LICENSE_EXPIRATION}.`); + if (!preparedAlert) { return state; } - const uiSettings = (await getUiSettingsService()).asScopedToClient( - services.savedObjectsClient - ); - const dateFormat: string = await uiSettings.get('dateFormat'); - const timezone: string = await uiSettings.get('dateFormat:tz'); - const emailAddress = await fetchDefaultEmailAddress(uiSettings); - if (!emailAddress) { - // TODO: we can do more here - logger.warn( - `Unable to send email for ${ALERT_TYPE_LICENSE_EXPIRATION} because there is no email configured.` - ); - return; - } + const { emailAddress, data: licenses, clusters, dateFormat } = preparedAlert; - const result: AlertState = { ...state }; + const result: AlertCommonState = { ...state }; + const defaultAlertState: AlertLicensePerClusterState = { + expiredCheckDateMS: 0, + ui: { + isFiring: false, + message: null, + severity: 0, + resolvedMS: 0, + lastCheckedMS: 0, + triggeredMS: 0, + }, + }; for (const license of licenses) { - const licenseState: AlertClusterState = state[license.clusterUuid] || {}; + const alertState: AlertLicensePerClusterState = + (state[license.clusterUuid] as AlertLicensePerClusterState) || defaultAlertState; + const cluster = clusters.find( + (c: AlertCommonCluster) => c.clusterUuid === license.clusterUuid + ); + if (!cluster) { + logger.warn(`Unable to find cluster for clusterUuid='${license.clusterUuid}'`); + continue; + } const $expiry = moment.utc(license.expiryDateMS); let isExpired = false; let severity = 0; @@ -123,31 +107,26 @@ export const getLicenseExpiration = ( } } - const ui: AlertClusterUiState = get(licenseState, 'ui', { - isFiring: false, - message: null, - severity: 0, - resolvedMS: 0, - expirationTime: 0, - }); + const ui = alertState.ui; + let triggered = ui.triggeredMS; let resolved = ui.resolvedMS; let message = ui.message; - let expiredCheckDate = licenseState.expiredCheckDateMS; + let expiredCheckDate = alertState.expiredCheckDateMS; const instance = services.alertInstanceFactory(ALERT_TYPE_LICENSE_EXPIRATION); if (isExpired) { - if (!licenseState.expiredCheckDateMS) { + if (!alertState.expiredCheckDateMS) { logger.debug(`License will expire soon, sending email`); - executeActions(instance, license, $expiry, dateFormat, emailAddress); - expiredCheckDate = moment().valueOf(); + executeActions(instance, cluster, $expiry, dateFormat, emailAddress); + expiredCheckDate = triggered = moment().valueOf(); } - message = getUiMessage(license, timezone); + message = getUiMessage(); resolved = 0; - } else if (!isExpired && licenseState.expiredCheckDateMS) { + } else if (!isExpired && alertState.expiredCheckDateMS) { logger.debug(`License expiration has been resolved, sending email`); - executeActions(instance, license, $expiry, dateFormat, emailAddress, true); + executeActions(instance, cluster, $expiry, dateFormat, emailAddress, true); expiredCheckDate = 0; - message = getUiMessage(license, timezone, true); + message = getUiMessage(true); resolved = moment().valueOf(); } @@ -159,8 +138,10 @@ export const getLicenseExpiration = ( isFiring: expiredCheckDate > 0, severity, resolvedMS: resolved, - }, - }; + triggeredMS: triggered, + lastCheckedMS: moment().valueOf(), + } as AlertLicensePerClusterUiState, + } as AlertLicensePerClusterState; } return result; diff --git a/x-pack/plugins/monitoring/server/alerts/types.d.ts b/x-pack/plugins/monitoring/server/alerts/types.d.ts index ff47d6f2ad4dc..b689d008b51a7 100644 --- a/x-pack/plugins/monitoring/server/alerts/types.d.ts +++ b/x-pack/plugins/monitoring/server/alerts/types.d.ts @@ -5,41 +5,79 @@ */ import { Moment } from 'moment'; import { AlertExecutorOptions } from '../../../alerting/server'; +import { AlertClusterStateState, AlertCommonPerClusterMessageTokenType } from './enums'; export interface AlertLicense { status: string; type: string; expiryDateMS: number; clusterUuid: string; - clusterName: string; } -export interface AlertState { - [clusterUuid: string]: AlertClusterState; +export interface AlertClusterState { + state: AlertClusterStateState; + clusterUuid: string; +} + +export interface AlertCommonState { + [clusterUuid: string]: AlertCommonPerClusterState; } -export interface AlertClusterState { - expiredCheckDateMS: number | Moment; - ui: AlertClusterUiState; +export interface AlertCommonPerClusterState { + ui: AlertCommonPerClusterUiState; } -export interface AlertClusterUiState { +export interface AlertClusterStatePerClusterState extends AlertCommonPerClusterState { + state: AlertClusterStateState; +} + +export interface AlertLicensePerClusterState extends AlertCommonPerClusterState { + expiredCheckDateMS: number; +} + +export interface AlertCommonPerClusterUiState { isFiring: boolean; severity: number; - message: string | null; + message: AlertCommonPerClusterMessage | null; resolvedMS: number; + lastCheckedMS: number; + triggeredMS: number; +} + +export interface AlertCommonPerClusterMessage { + text: string; // Do this. #link this is a link #link + tokens?: AlertCommonPerClusterMessageToken[]; +} + +export interface AlertCommonPerClusterMessageToken { + startToken: string; + endToken?: string; + type: AlertCommonPerClusterMessageTokenType; +} + +export interface AlertCommonPerClusterMessageLinkToken extends AlertCommonPerClusterMessageToken { + url?: string; +} + +export interface AlertCommonPerClusterMessageTimeToken extends AlertCommonPerClusterMessageToken { + isRelative: boolean; + isAbsolute: boolean; +} + +export interface AlertLicensePerClusterUiState extends AlertCommonPerClusterUiState { expirationTime: number; } -export interface AlertCluster { +export interface AlertCommonCluster { clusterUuid: string; + clusterName: string; } -export interface LicenseExpirationAlertExecutorOptions extends AlertExecutorOptions { - state: AlertState; +export interface AlertCommonExecutorOptions extends AlertExecutorOptions { + state: AlertCommonState; } -export interface AlertParams { +export interface AlertCommonParams { dateFormat: string; timezone: string; } diff --git a/x-pack/plugins/monitoring/server/lib/alerts/cluster_state.lib.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/cluster_state.lib.test.ts new file mode 100644 index 0000000000000..81e375734cc50 --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/cluster_state.lib.test.ts @@ -0,0 +1,70 @@ +/* + * 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 { executeActions, getUiMessage } from './cluster_state.lib'; +import { AlertClusterStateState } from '../../alerts/enums'; +import { AlertCommonPerClusterMessageLinkToken } from '../../alerts/types'; + +describe('clusterState lib', () => { + describe('executeActions', () => { + const clusterName = 'clusterA'; + const instance: any = { scheduleActions: jest.fn() }; + const license: any = { clusterName }; + const status = AlertClusterStateState.Green; + const emailAddress = 'test@test.com'; + + beforeEach(() => { + instance.scheduleActions.mockClear(); + }); + + it('should schedule actions when firing', () => { + executeActions(instance, license, status, emailAddress, false); + expect(instance.scheduleActions).toHaveBeenCalledWith('default', { + subject: 'NEW X-Pack Monitoring: Cluster Status', + message: `Allocate missing replica shards for cluster '${clusterName}'`, + to: emailAddress, + }); + }); + + it('should have a different message for red state', () => { + executeActions(instance, license, AlertClusterStateState.Red, emailAddress, false); + expect(instance.scheduleActions).toHaveBeenCalledWith('default', { + subject: 'NEW X-Pack Monitoring: Cluster Status', + message: `Allocate missing primary and replica shards for cluster '${clusterName}'`, + to: emailAddress, + }); + }); + + it('should schedule actions when resolved', () => { + executeActions(instance, license, status, emailAddress, true); + expect(instance.scheduleActions).toHaveBeenCalledWith('default', { + subject: 'RESOLVED X-Pack Monitoring: Cluster Status', + message: `This cluster alert has been resolved: Allocate missing replica shards for cluster '${clusterName}'`, + to: emailAddress, + }); + }); + }); + + describe('getUiMessage', () => { + it('should return a message when firing', () => { + const message = getUiMessage(AlertClusterStateState.Red, false); + expect(message.text).toBe( + `Elasticsearch cluster status is red. #start_linkAllocate missing primary and replica shards#end_link` + ); + expect(message.tokens && message.tokens.length).toBe(1); + expect(message.tokens && message.tokens[0].startToken).toBe('#start_link'); + expect(message.tokens && message.tokens[0].endToken).toBe('#end_link'); + expect( + message.tokens && (message.tokens[0] as AlertCommonPerClusterMessageLinkToken).url + ).toBe('elasticsearch/indices'); + }); + + it('should return a message when resolved', () => { + const message = getUiMessage(AlertClusterStateState.Green, true); + expect(message.text).toBe(`Elasticsearch cluster status is green.`); + expect(message.tokens).not.toBeDefined(); + }); + }); +}); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/cluster_state.lib.ts b/x-pack/plugins/monitoring/server/lib/alerts/cluster_state.lib.ts new file mode 100644 index 0000000000000..ae66d603507ca --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/cluster_state.lib.ts @@ -0,0 +1,88 @@ +/* + * 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 { AlertInstance } from '../../../../alerting/server'; +import { + AlertCommonCluster, + AlertCommonPerClusterMessage, + AlertCommonPerClusterMessageLinkToken, +} from '../../alerts/types'; +import { AlertClusterStateState, AlertCommonPerClusterMessageTokenType } from '../../alerts/enums'; + +const RESOLVED_SUBJECT = i18n.translate('xpack.monitoring.alerts.clusterStatus.resolvedSubject', { + defaultMessage: 'RESOLVED X-Pack Monitoring: Cluster Status', +}); + +const NEW_SUBJECT = i18n.translate('xpack.monitoring.alerts.clusterStatus.newSubject', { + defaultMessage: 'NEW X-Pack Monitoring: Cluster Status', +}); + +const RED_STATUS_MESSAGE = i18n.translate('xpack.monitoring.alerts.clusterStatus.redMessage', { + defaultMessage: 'Allocate missing primary and replica shards', +}); + +const YELLOW_STATUS_MESSAGE = i18n.translate( + 'xpack.monitoring.alerts.clusterStatus.yellowMessage', + { + defaultMessage: 'Allocate missing replica shards', + } +); + +export function executeActions( + instance: AlertInstance, + cluster: AlertCommonCluster, + status: AlertClusterStateState, + emailAddress: string, + resolved: boolean = false +) { + const message = + status === AlertClusterStateState.Red ? RED_STATUS_MESSAGE : YELLOW_STATUS_MESSAGE; + if (resolved) { + instance.scheduleActions('default', { + subject: RESOLVED_SUBJECT, + message: `This cluster alert has been resolved: ${message} for cluster '${cluster.clusterName}'`, + to: emailAddress, + }); + } else { + instance.scheduleActions('default', { + subject: NEW_SUBJECT, + message: `${message} for cluster '${cluster.clusterName}'`, + to: emailAddress, + }); + } +} + +export function getUiMessage( + status: AlertClusterStateState, + resolved: boolean = false +): AlertCommonPerClusterMessage { + if (resolved) { + return { + text: i18n.translate('xpack.monitoring.alerts.clusterStatus.ui.resolvedMessage', { + defaultMessage: `Elasticsearch cluster status is green.`, + }), + }; + } + const message = + status === AlertClusterStateState.Red ? RED_STATUS_MESSAGE : YELLOW_STATUS_MESSAGE; + return { + text: i18n.translate('xpack.monitoring.alerts.clusterStatus.ui.firingMessage', { + defaultMessage: `Elasticsearch cluster status is {status}. #start_link{message}#end_link`, + values: { + status, + message, + }, + }), + tokens: [ + { + startToken: '#start_link', + endToken: '#end_link', + type: AlertCommonPerClusterMessageTokenType.Link, + url: 'elasticsearch/indices', + } as AlertCommonPerClusterMessageLinkToken, + ], + }; +} diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_state.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_state.test.ts new file mode 100644 index 0000000000000..642ae3c39a027 --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_state.test.ts @@ -0,0 +1,39 @@ +/* + * 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 { fetchClusterState } from './fetch_cluster_state'; + +describe('fetchClusterState', () => { + it('should return the cluster state', async () => { + const status = 'green'; + const clusterUuid = 'sdfdsaj34434'; + const callCluster = jest.fn(() => ({ + hits: { + hits: [ + { + _source: { + cluster_state: { + status, + }, + cluster_uuid: clusterUuid, + }, + }, + ], + }, + })); + + const clusters = [{ clusterUuid, clusterName: 'foo' }]; + const index = '.monitoring-es-*'; + + const state = await fetchClusterState(callCluster, clusters, index); + expect(state).toEqual([ + { + state: status, + clusterUuid, + }, + ]); + }); +}); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_state.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_state.ts new file mode 100644 index 0000000000000..66ea30d5f2e96 --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_state.ts @@ -0,0 +1,53 @@ +/* + * 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 { get } from 'lodash'; +import { AlertCommonCluster, AlertClusterState } from '../../alerts/types'; + +export async function fetchClusterState( + callCluster: any, + clusters: AlertCommonCluster[], + index: string +): Promise { + const params = { + index, + filterPath: ['hits.hits._source.cluster_state.status', 'hits.hits._source.cluster_uuid'], + body: { + size: 1, + sort: [{ timestamp: { order: 'desc' } }], + query: { + bool: { + filter: [ + { + terms: { + cluster_uuid: clusters.map(cluster => cluster.clusterUuid), + }, + }, + { + term: { + type: 'cluster_stats', + }, + }, + { + range: { + timestamp: { + gte: 'now-2m', + }, + }, + }, + ], + }, + }, + }, + }; + + const response = await callCluster('search', params); + return get(response, 'hits.hits', []).map((hit: any) => { + return { + state: get(hit, '_source.cluster_state.status'), + clusterUuid: get(hit, '_source.cluster_uuid'), + }; + }); +} diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.test.ts index 78eb9773df15f..7a9b61f37707b 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.test.ts @@ -6,21 +6,51 @@ import { fetchClusters } from './fetch_clusters'; describe('fetchClusters', () => { + const clusterUuid = '1sdfds734'; + const clusterName = 'monitoring'; + it('return a list of clusters', async () => { const callCluster = jest.fn().mockImplementation(() => ({ - aggregations: { - clusters: { - buckets: [ - { - key: 'clusterA', + hits: { + hits: [ + { + _source: { + cluster_uuid: clusterUuid, + cluster_name: clusterName, + }, + }, + ], + }, + })); + const index = '.monitoring-es-*'; + const result = await fetchClusters(callCluster, index); + expect(result).toEqual([{ clusterUuid, clusterName }]); + }); + + it('return the metadata name if available', async () => { + const metadataName = 'custom-monitoring'; + const callCluster = jest.fn().mockImplementation(() => ({ + hits: { + hits: [ + { + _source: { + cluster_uuid: clusterUuid, + cluster_name: clusterName, + cluster_settings: { + cluster: { + metadata: { + display_name: metadataName, + }, + }, + }, }, - ], - }, + }, + ], }, })); const index = '.monitoring-es-*'; const result = await fetchClusters(callCluster, index); - expect(result).toEqual([{ clusterUuid: 'clusterA' }]); + expect(result).toEqual([{ clusterUuid, clusterName: metadataName }]); }); it('should limit the time period in the query', async () => { diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts index 8ef7339618a2c..d1513ac16fb15 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_clusters.ts @@ -4,18 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ import { get } from 'lodash'; -import { AlertCluster } from '../../alerts/types'; +import { AlertCommonCluster } from '../../alerts/types'; -interface AggregationResult { - key: string; -} - -export async function fetchClusters(callCluster: any, index: string): Promise { +export async function fetchClusters( + callCluster: any, + index: string +): Promise { const params = { index, - filterPath: 'aggregations.clusters.buckets', + filterPath: [ + 'hits.hits._source.cluster_settings.cluster.metadata.display_name', + 'hits.hits._source.cluster_uuid', + 'hits.hits._source.cluster_name', + ], body: { - size: 0, + size: 1000, query: { bool: { filter: [ @@ -34,19 +37,21 @@ export async function fetchClusters(callCluster: any, index: string): Promise ({ - clusterUuid: bucket.key, - })); + return get(response, 'hits.hits', []).map((hit: any) => { + const clusterName: string = + get(hit, '_source.cluster_settings.cluster.metadata.display_name') || + get(hit, '_source.cluster_name') || + get(hit, '_source.cluster_uuid'); + return { + clusterUuid: get(hit, '_source.cluster_uuid'), + clusterName, + }; + }); } diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.test.ts index dd6c074e68b1f..9dcb4ffb82a5f 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.test.ts @@ -6,28 +6,28 @@ import { fetchLicenses } from './fetch_licenses'; describe('fetchLicenses', () => { + const clusterName = 'MyCluster'; + const clusterUuid = 'clusterA'; + const license = { + status: 'active', + expiry_date_in_millis: 1579532493876, + type: 'basic', + }; + it('return a list of licenses', async () => { - const clusterName = 'MyCluster'; - const clusterUuid = 'clusterA'; - const license = { - status: 'active', - expiry_date_in_millis: 1579532493876, - type: 'basic', - }; const callCluster = jest.fn().mockImplementation(() => ({ hits: { hits: [ { _source: { license, - cluster_name: clusterName, cluster_uuid: clusterUuid, }, }, ], }, })); - const clusters = [{ clusterUuid }]; + const clusters = [{ clusterUuid, clusterName }]; const index = '.monitoring-es-*'; const result = await fetchLicenses(callCluster, clusters, index); expect(result).toEqual([ @@ -36,15 +36,13 @@ describe('fetchLicenses', () => { type: license.type, expiryDateMS: license.expiry_date_in_millis, clusterUuid, - clusterName, }, ]); }); it('should only search for the clusters provided', async () => { - const clusterUuid = 'clusterA'; const callCluster = jest.fn(); - const clusters = [{ clusterUuid }]; + const clusters = [{ clusterUuid, clusterName }]; const index = '.monitoring-es-*'; await fetchLicenses(callCluster, clusters, index); const params = callCluster.mock.calls[0][1]; @@ -52,54 +50,11 @@ describe('fetchLicenses', () => { }); it('should limit the time period in the query', async () => { - const clusterUuid = 'clusterA'; const callCluster = jest.fn(); - const clusters = [{ clusterUuid }]; + const clusters = [{ clusterUuid, clusterName }]; const index = '.monitoring-es-*'; await fetchLicenses(callCluster, clusters, index); const params = callCluster.mock.calls[0][1]; expect(params.body.query.bool.filter[2].range.timestamp.gte).toBe('now-2m'); }); - - it('should give priority to the metadata name', async () => { - const clusterName = 'MyCluster'; - const clusterUuid = 'clusterA'; - const license = { - status: 'active', - expiry_date_in_millis: 1579532493876, - type: 'basic', - }; - const callCluster = jest.fn().mockImplementation(() => ({ - hits: { - hits: [ - { - _source: { - license, - cluster_name: 'fakeName', - cluster_uuid: clusterUuid, - cluster_settings: { - cluster: { - metadata: { - display_name: clusterName, - }, - }, - }, - }, - }, - ], - }, - })); - const clusters = [{ clusterUuid }]; - const index = '.monitoring-es-*'; - const result = await fetchLicenses(callCluster, clusters, index); - expect(result).toEqual([ - { - status: license.status, - type: license.type, - expiryDateMS: license.expiry_date_in_millis, - clusterUuid, - clusterName, - }, - ]); - }); }); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts index 31a68e8aa9c3e..5b05c907e796e 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts @@ -4,21 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ import { get } from 'lodash'; -import { AlertLicense, AlertCluster } from '../../alerts/types'; +import { AlertLicense, AlertCommonCluster } from '../../alerts/types'; export async function fetchLicenses( callCluster: any, - clusters: AlertCluster[], + clusters: AlertCommonCluster[], index: string ): Promise { const params = { index, - filterPath: [ - 'hits.hits._source.license.*', - 'hits.hits._source.cluster_settings.cluster.metadata.display_name', - 'hits.hits._source.cluster_uuid', - 'hits.hits._source.cluster_name', - ], + filterPath: ['hits.hits._source.license.*', 'hits.hits._source.cluster_uuid'], body: { size: 1, sort: [{ timestamp: { order: 'desc' } }], @@ -50,17 +45,12 @@ export async function fetchLicenses( const response = await callCluster('search', params); return get(response, 'hits.hits', []).map((hit: any) => { - const clusterName: string = - get(hit, '_source.cluster_settings.cluster.metadata.display_name') || - get(hit, '_source.cluster_name') || - get(hit, '_source.cluster_uuid'); const rawLicense: any = get(hit, '_source.license', {}); const license: AlertLicense = { status: rawLicense.status, type: rawLicense.type, expiryDateMS: rawLicense.expiry_date_in_millis, clusterUuid: get(hit, '_source.cluster_uuid'), - clusterName, }; return license; }); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts new file mode 100644 index 0000000000000..a3bcb61afacd6 --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts @@ -0,0 +1,122 @@ +/* + * 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 { fetchStatus } from './fetch_status'; +import { AlertCommonPerClusterState } from '../../alerts/types'; + +describe('fetchStatus', () => { + const alertType = 'monitoringTest'; + const log = { warn: jest.fn() }; + const start = 0; + const end = 0; + const id = 1; + const defaultUiState = { + isFiring: false, + severity: 0, + message: null, + resolvedMS: 0, + lastCheckedMS: 0, + triggeredMS: 0, + }; + const alertsClient = { + find: jest.fn(() => ({ + total: 1, + data: [ + { + id, + }, + ], + })), + getAlertState: jest.fn(() => ({ + alertTypeState: { + state: { + ui: defaultUiState, + } as AlertCommonPerClusterState, + }, + })), + }; + + afterEach(() => { + (alertsClient.find as jest.Mock).mockClear(); + (alertsClient.getAlertState as jest.Mock).mockClear(); + }); + + it('should fetch from the alerts client', async () => { + const status = await fetchStatus(alertsClient as any, [alertType], start, end, log as any); + expect(status).toEqual([]); + }); + + it('should return alerts that are firing', async () => { + alertsClient.getAlertState = jest.fn(() => ({ + alertTypeState: { + state: { + ui: { + ...defaultUiState, + isFiring: true, + }, + } as AlertCommonPerClusterState, + }, + })); + + const status = await fetchStatus(alertsClient as any, [alertType], start, end, log as any); + expect(status.length).toBe(1); + expect(status[0].type).toBe(alertType); + expect(status[0].isFiring).toBe(true); + }); + + it('should return alerts that have been resolved in the time period', async () => { + alertsClient.getAlertState = jest.fn(() => ({ + alertTypeState: { + state: { + ui: { + ...defaultUiState, + resolvedMS: 1500, + }, + } as AlertCommonPerClusterState, + }, + })); + + const customStart = 1000; + const customEnd = 2000; + + const status = await fetchStatus( + alertsClient as any, + [alertType], + customStart, + customEnd, + log as any + ); + expect(status.length).toBe(1); + expect(status[0].type).toBe(alertType); + expect(status[0].isFiring).toBe(false); + }); + + it('should pass in the right filter to the alerts client', async () => { + await fetchStatus(alertsClient as any, [alertType], start, end, log as any); + expect((alertsClient.find as jest.Mock).mock.calls[0][0].options.filter).toBe( + `alert.attributes.alertTypeId:${alertType}` + ); + }); + + it('should return nothing if no alert state is found', async () => { + alertsClient.getAlertState = jest.fn(() => ({ + alertTypeState: null, + })) as any; + + const status = await fetchStatus(alertsClient as any, [alertType], start, end, log as any); + expect(status).toEqual([]); + }); + + it('should return nothing if no alerts are found', async () => { + alertsClient.find = jest.fn(() => ({ + total: 0, + data: [], + })) as any; + + const status = await fetchStatus(alertsClient as any, [alertType], start, end, log as any); + expect(status).toEqual([]); + }); +}); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.ts index 9f7c1d5a994d2..bf6ee965d3b2f 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.ts @@ -4,81 +4,53 @@ * you may not use this file except in compliance with the Elastic License. */ import moment from 'moment'; -import { get } from 'lodash'; -import { AlertClusterState } from '../../alerts/types'; -import { ALERT_TYPES, LOGGING_TAG } from '../../../common/constants'; +import { Logger } from '../../../../../../src/core/server'; +import { AlertCommonPerClusterState } from '../../alerts/types'; +import { AlertsClient } from '../../../../alerting/server'; export async function fetchStatus( - callCluster: any, + alertsClient: AlertsClient, + alertTypes: string[], start: number, end: number, - clusterUuid: string, - server: any + log: Logger ): Promise { - // TODO: this shouldn't query task manager directly but rather - // use an api exposed by the alerting/actions plugin - // See https://github.com/elastic/kibana/issues/48442 const statuses = await Promise.all( - ALERT_TYPES.map( + alertTypes.map( type => new Promise(async (resolve, reject) => { - try { - const params = { - index: '.kibana_task_manager', - filterPath: ['hits.hits._source.task.state'], - body: { - size: 1, - sort: [{ updated_at: { order: 'desc' } }], - query: { - bool: { - filter: [ - { - term: { - 'task.taskType': `alerting:${type}`, - }, - }, - ], - }, - }, - }, - }; - - const response = await callCluster('search', params); - const state = get(response, 'hits.hits[0]._source.task.state', '{}'); - const clusterState: AlertClusterState = get( - JSON.parse(state), - `alertTypeState.${clusterUuid}`, - { - expiredCheckDateMS: 0, - ui: { - isFiring: false, - message: null, - severity: 0, - resolvedMS: 0, - expirationTime: 0, - }, - } - ); - const isInBetween = moment(clusterState.ui.resolvedMS).isBetween(start, end); - if (clusterState.ui.isFiring || isInBetween) { - return resolve({ - type, - ...clusterState.ui, - }); - } + // We need to get the id from the alertTypeId + const alerts = await alertsClient.find({ + options: { + filter: `alert.attributes.alertTypeId:${type}`, + }, + }); + if (alerts.total === 0) { return resolve(false); - } catch (err) { - const reason = get(err, 'body.error.type'); - if (reason === 'index_not_found_exception') { - server.log( - ['error', LOGGING_TAG], - `Unable to fetch alerts. Alerts depends on task manager, which has not been started yet.` - ); - } else { - server.log(['error', LOGGING_TAG], err.message); - } + } + + if (alerts.total !== 1) { + log.warn(`Found more than one alert for type ${type} which is unexpected.`); + } + + const id = alerts.data[0].id; + + // Now that we have the id, we can get the state + const states = await alertsClient.getAlertState({ id }); + if (!states || !states.alertTypeState) { + log.warn(`No alert states found for type ${type} which is unexpected.`); return resolve(false); } + + const state = Object.values(states.alertTypeState)[0] as AlertCommonPerClusterState; + const isInBetween = moment(state.ui.resolvedMS).isBetween(start, end); + if (state.ui.isFiring || isInBetween) { + return resolve({ + type, + ...state.ui, + }); + } + return resolve(false); }) ) ); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/get_prepared_alert.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/get_prepared_alert.test.ts new file mode 100644 index 0000000000000..1840a2026a753 --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/get_prepared_alert.test.ts @@ -0,0 +1,163 @@ +/* + * 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 { getPreparedAlert } from './get_prepared_alert'; +import { fetchClusters } from './fetch_clusters'; +import { fetchDefaultEmailAddress } from './fetch_default_email_address'; + +jest.mock('./fetch_clusters', () => ({ + fetchClusters: jest.fn(), +})); + +jest.mock('./fetch_default_email_address', () => ({ + fetchDefaultEmailAddress: jest.fn(), +})); + +describe('getPreparedAlert', () => { + const uiSettings = { get: jest.fn() }; + const alertType = 'test'; + const getUiSettingsService = async () => ({ + asScopedToClient: () => uiSettings, + }); + const monitoringCluster = null; + const logger = { warn: jest.fn() }; + const ccsEnabled = false; + const services = { + callCluster: jest.fn(), + savedObjectsClient: null, + }; + const emailAddress = 'foo@foo.com'; + const data = [{ foo: 1 }]; + const dataFetcher = () => data; + const clusterName = 'MonitoringCluster'; + const clusterUuid = 'sdf34sdf'; + const clusters = [{ clusterName, clusterUuid }]; + + afterEach(() => { + (uiSettings.get as jest.Mock).mockClear(); + (services.callCluster as jest.Mock).mockClear(); + (fetchClusters as jest.Mock).mockClear(); + (fetchDefaultEmailAddress as jest.Mock).mockClear(); + }); + + beforeEach(() => { + (fetchClusters as jest.Mock).mockImplementation(() => clusters); + (fetchDefaultEmailAddress as jest.Mock).mockImplementation(() => emailAddress); + }); + + it('should return fields as expected', async () => { + (uiSettings.get as jest.Mock).mockImplementation(() => { + return emailAddress; + }); + + const alert = await getPreparedAlert( + alertType, + getUiSettingsService as any, + monitoringCluster as any, + logger as any, + ccsEnabled, + services as any, + dataFetcher as any + ); + + expect(alert && alert.emailAddress).toBe(emailAddress); + expect(alert && alert.data).toBe(data); + }); + + it('should add ccs if specified', async () => { + const ccsClusterName = 'remoteCluster'; + (services.callCluster as jest.Mock).mockImplementation(() => { + return { + [ccsClusterName]: { + connected: true, + }, + }; + }); + + await getPreparedAlert( + alertType, + getUiSettingsService as any, + monitoringCluster as any, + logger as any, + true, + services as any, + dataFetcher as any + ); + + expect((fetchClusters as jest.Mock).mock.calls[0][1].includes(ccsClusterName)).toBe(true); + }); + + it('should ignore ccs if no remote clusters are available', async () => { + const ccsClusterName = 'remoteCluster'; + (services.callCluster as jest.Mock).mockImplementation(() => { + return { + [ccsClusterName]: { + connected: false, + }, + }; + }); + + await getPreparedAlert( + alertType, + getUiSettingsService as any, + monitoringCluster as any, + logger as any, + true, + services as any, + dataFetcher as any + ); + + expect((fetchClusters as jest.Mock).mock.calls[0][1].includes(ccsClusterName)).toBe(false); + }); + + it('should pass in the clusters into the data fetcher', async () => { + const customDataFetcher = jest.fn(() => data); + + await getPreparedAlert( + alertType, + getUiSettingsService as any, + monitoringCluster as any, + logger as any, + true, + services as any, + customDataFetcher as any + ); + + expect((customDataFetcher as jest.Mock).mock.calls[0][1]).toBe(clusters); + }); + + it('should return nothing if the data fetcher returns nothing', async () => { + const customDataFetcher = jest.fn(() => []); + + const result = await getPreparedAlert( + alertType, + getUiSettingsService as any, + monitoringCluster as any, + logger as any, + true, + services as any, + customDataFetcher as any + ); + + expect(result).toBe(null); + }); + + it('should return nothing if there is no email address', async () => { + (fetchDefaultEmailAddress as jest.Mock).mockImplementation(() => null); + + const result = await getPreparedAlert( + alertType, + getUiSettingsService as any, + monitoringCluster as any, + logger as any, + true, + services as any, + dataFetcher as any + ); + + expect(result).toBe(null); + }); +}); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/get_prepared_alert.ts b/x-pack/plugins/monitoring/server/lib/alerts/get_prepared_alert.ts new file mode 100644 index 0000000000000..83a9e26e4c589 --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/alerts/get_prepared_alert.ts @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Logger, ICustomClusterClient, UiSettingsServiceStart } from 'kibana/server'; +import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; +import { AlertServices } from '../../../../alerting/server'; +import { AlertCommonCluster } from '../../alerts/types'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../common/constants'; +import { fetchAvailableCcs } from './fetch_available_ccs'; +import { getCcsIndexPattern } from './get_ccs_index_pattern'; +import { fetchClusters } from './fetch_clusters'; +import { fetchDefaultEmailAddress } from './fetch_default_email_address'; + +export interface PreparedAlert { + emailAddress: string; + clusters: AlertCommonCluster[]; + data: any[]; + timezone: string; + dateFormat: string; +} + +async function getCallCluster( + monitoringCluster: ICustomClusterClient, + services: Pick +): Promise { + if (!monitoringCluster) { + return services.callCluster; + } + + return monitoringCluster.callAsInternalUser; +} + +export async function getPreparedAlert( + alertType: string, + getUiSettingsService: () => Promise, + monitoringCluster: ICustomClusterClient, + logger: Logger, + ccsEnabled: boolean, + services: Pick, + dataFetcher: ( + callCluster: CallCluster, + clusters: AlertCommonCluster[], + esIndexPattern: string + ) => Promise +): Promise { + const callCluster = await getCallCluster(monitoringCluster, services); + + // Support CCS use cases by querying to find available remote clusters + // and then adding those to the index pattern we are searching against + let esIndexPattern = INDEX_PATTERN_ELASTICSEARCH; + if (ccsEnabled) { + const availableCcs = await fetchAvailableCcs(callCluster); + if (availableCcs.length > 0) { + esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs); + } + } + + const clusters = await fetchClusters(callCluster, esIndexPattern); + + // Fetch the specific data + const data = await dataFetcher(callCluster, clusters, esIndexPattern); + if (data.length === 0) { + logger.warn(`No data found for ${alertType}.`); + return null; + } + + const uiSettings = (await getUiSettingsService()).asScopedToClient(services.savedObjectsClient); + const dateFormat: string = await uiSettings.get('dateFormat'); + const timezone: string = await uiSettings.get('dateFormat:tz'); + const emailAddress = await fetchDefaultEmailAddress(uiSettings); + if (!emailAddress) { + // TODO: we can do more here + logger.warn(`Unable to send email for ${alertType} because there is no email configured.`); + return null; + } + + return { + emailAddress, + data, + clusters, + dateFormat, + timezone, + }; +} diff --git a/x-pack/plugins/monitoring/server/lib/alerts/license_expiration.lib.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/license_expiration.lib.test.ts index 1a2eb1e44be84..6c0301b6cc347 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/license_expiration.lib.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/license_expiration.lib.test.ts @@ -39,17 +39,26 @@ describe('licenseExpiration lib', () => { }); describe('getUiMessage', () => { - const timezone = 'Europe/London'; - const license: any = { expiryDateMS: moment.tz('2020-01-20 08:00:00', timezone).utc() }; - it('should return a message when firing', () => { - const message = getUiMessage(license, timezone, false); - expect(message).toBe(`This cluster's license is going to expire in #relative at #absolute.`); + const message = getUiMessage(false); + expect(message.text).toBe( + `This cluster's license is going to expire in #relative at #absolute. #start_linkPlease update your license#end_link` + ); + // LOL How do I avoid this in TS???? + if (!message.tokens) { + return expect(false).toBe(true); + } + expect(message.tokens.length).toBe(3); + expect(message.tokens[0].startToken).toBe('#relative'); + expect(message.tokens[1].startToken).toBe('#absolute'); + expect(message.tokens[2].startToken).toBe('#start_link'); + expect(message.tokens[2].endToken).toBe('#end_link'); }); it('should return a message when resolved', () => { - const message = getUiMessage(license, timezone, true); - expect(message).toBe(`This cluster's license is active.`); + const message = getUiMessage(true); + expect(message.text).toBe(`This cluster's license is active.`); + expect(message.tokens).not.toBeDefined(); }); }); }); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/license_expiration.lib.ts b/x-pack/plugins/monitoring/server/lib/alerts/license_expiration.lib.ts index 41b68d69bbd25..a590021a2f29b 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/license_expiration.lib.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/license_expiration.lib.ts @@ -6,7 +6,13 @@ import { Moment } from 'moment-timezone'; import { i18n } from '@kbn/i18n'; import { AlertInstance } from '../../../../alerting/server'; -import { AlertLicense } from '../../alerts/types'; +import { + AlertCommonPerClusterMessageLinkToken, + AlertCommonPerClusterMessageTimeToken, + AlertCommonCluster, + AlertCommonPerClusterMessage, +} from '../../alerts/types'; +import { AlertCommonPerClusterMessageTokenType } from '../../alerts/enums'; const RESOLVED_SUBJECT = i18n.translate( 'xpack.monitoring.alerts.licenseExpiration.resolvedSubject', @@ -21,7 +27,7 @@ const NEW_SUBJECT = i18n.translate('xpack.monitoring.alerts.licenseExpiration.ne export function executeActions( instance: AlertInstance, - license: AlertLicense, + cluster: AlertCommonCluster, $expiry: Moment, dateFormat: string, emailAddress: string, @@ -31,14 +37,14 @@ export function executeActions( instance.scheduleActions('default', { subject: RESOLVED_SUBJECT, message: `This cluster alert has been resolved: Cluster '${ - license.clusterName + cluster.clusterName }' license was going to expire on ${$expiry.format(dateFormat)}.`, to: emailAddress, }); } else { instance.scheduleActions('default', { subject: NEW_SUBJECT, - message: `Cluster '${license.clusterName}' license is going to expire on ${$expiry.format( + message: `Cluster '${cluster.clusterName}' license is going to expire on ${$expiry.format( dateFormat )}. Please update your license.`, to: emailAddress, @@ -46,13 +52,43 @@ export function executeActions( } } -export function getUiMessage(license: AlertLicense, timezone: string, resolved: boolean = false) { +export function getUiMessage(resolved: boolean = false): AlertCommonPerClusterMessage { if (resolved) { - return i18n.translate('xpack.monitoring.alerts.licenseExpiration.ui.resolvedMessage', { - defaultMessage: `This cluster's license is active.`, - }); + return { + text: i18n.translate('xpack.monitoring.alerts.licenseExpiration.ui.resolvedMessage', { + defaultMessage: `This cluster's license is active.`, + }), + }; } - return i18n.translate('xpack.monitoring.alerts.licenseExpiration.ui.firingMessage', { - defaultMessage: `This cluster's license is going to expire in #relative at #absolute.`, + const linkText = i18n.translate('xpack.monitoring.alerts.licenseExpiration.linkText', { + defaultMessage: 'Please update your license', }); + return { + text: i18n.translate('xpack.monitoring.alerts.licenseExpiration.ui.firingMessage', { + defaultMessage: `This cluster's license is going to expire in #relative at #absolute. #start_link{linkText}#end_link`, + values: { + linkText, + }, + }), + tokens: [ + { + startToken: '#relative', + type: AlertCommonPerClusterMessageTokenType.Time, + isRelative: true, + isAbsolute: false, + } as AlertCommonPerClusterMessageTimeToken, + { + startToken: '#absolute', + type: AlertCommonPerClusterMessageTokenType.Time, + isAbsolute: true, + isRelative: false, + } as AlertCommonPerClusterMessageTimeToken, + { + startToken: '#start_link', + endToken: '#end_link', + type: AlertCommonPerClusterMessageTokenType.Link, + url: 'license', + } as AlertCommonPerClusterMessageLinkToken, + ], + }; } diff --git a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.js b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.js index c5091c36c3bbe..1bddede52207b 100644 --- a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.js +++ b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_from_request.js @@ -29,6 +29,7 @@ import { CODE_PATH_BEATS, CODE_PATH_APM, KIBANA_ALERTING_ENABLED, + ALERT_TYPES, } from '../../../common/constants'; import { getApmsForClusters } from '../apm/get_apms_for_clusters'; import { i18n } from '@kbn/i18n'; @@ -102,15 +103,8 @@ export async function getClustersFromRequest( if (isInCodePath(codePaths, [CODE_PATH_ALERTS])) { if (KIBANA_ALERTING_ENABLED) { - const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring'); - const callCluster = (...args) => callWithRequest(req, ...args); - cluster.alerts = await fetchStatus( - callCluster, - start, - end, - cluster.cluster_uuid, - req.server - ); + const alertsClient = req.getAlertsClient ? req.getAlertsClient() : null; + cluster.alerts = await fetchStatus(alertsClient, ALERT_TYPES, start, end, req.logger); } else { cluster.alerts = await alertsClusterSearch( req, diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 24d8bcaa4397c..784226dca66fe 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -47,6 +47,7 @@ import { PluginSetupContract as AlertingPluginSetupContract, } from '../../alerting/server'; import { getLicenseExpiration } from './alerts/license_expiration'; +import { getClusterState } from './alerts/cluster_state'; import { InfraPluginSetup } from '../../infra/server'; export interface LegacyAPI { @@ -154,6 +155,17 @@ export class Plugin { config.ui.ccs.enabled ) ); + plugins.alerting.registerType( + getClusterState( + async () => { + const coreStart = (await core.getStartServices())[0]; + return coreStart.uiSettings; + }, + cluster, + this.getLogger, + config.ui.ccs.enabled + ) + ); } // Initialize telemetry diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/alerts.js b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/alerts.js index 56922bd8e87e2..d5a43d32f600a 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/alerts.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/alerts.js @@ -8,8 +8,12 @@ import { schema } from '@kbn/config-schema'; import { isFunction } from 'lodash'; import { ALERT_TYPE_LICENSE_EXPIRATION, + ALERT_TYPE_CLUSTER_STATE, MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS, + ALERT_TYPES, } from '../../../../../common/constants'; +import { handleError } from '../../../../lib/errors'; +import { fetchStatus } from '../../../../lib/alerts/fetch_status'; async function createAlerts(req, alertsClient, { selectedEmailActionId }) { const createdAlerts = []; @@ -17,7 +21,21 @@ async function createAlerts(req, alertsClient, { selectedEmailActionId }) { // Create alerts const ALERT_TYPES = { [ALERT_TYPE_LICENSE_EXPIRATION]: { - schedule: { interval: '10s' }, + schedule: { interval: '1m' }, + actions: [ + { + group: 'default', + id: selectedEmailActionId, + params: { + subject: '{{context.subject}}', + message: `{{context.message}}`, + to: ['{{context.to}}'], + }, + }, + ], + }, + [ALERT_TYPE_CLUSTER_STATE]: { + schedule: { interval: '1m' }, actions: [ { group: 'default', @@ -86,4 +104,37 @@ export function createKibanaAlertsRoute(server) { return { alerts, emailResponse }; }, }); + + server.route({ + method: 'POST', + path: '/api/monitoring/v1/alert_status', + config: { + validate: { + payload: schema.object({ + timeRange: schema.object({ + min: schema.string(), + max: schema.string(), + }), + }), + }, + }, + async handler(req, headers) { + const alertsClient = isFunction(req.getAlertsClient) ? req.getAlertsClient() : null; + if (!alertsClient) { + return headers.response().code(404); + } + + const start = req.payload.timeRange.min; + const end = req.payload.timeRange.max; + let alerts; + + try { + alerts = await fetchStatus(alertsClient, ALERT_TYPES, start, end, req.logger); + } catch (err) { + throw handleError(err, req); + } + + return { alerts }; + }, + }); } From 813d6cb796b42738fc24db43b0df2f4d337a06ed Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Mon, 6 Apr 2020 21:42:43 +0200 Subject: [PATCH 2/8] [SIEM] View signal in default timeline (#62616) * adds test data * adds 'View a signal in timeline' test * implements test * fixes implementation * changes view signal for investigate signal --- .../integration/detections_timeline.spec.ts | 43 + .../plugins/siem/cypress/objects/timeline.ts | 10 + .../siem/cypress/screens/detections.ts | 6 + .../plugins/siem/cypress/screens/timeline.ts | 2 + .../plugins/siem/cypress/tasks/detections.ts | 14 + .../es_archives/timeline_signals/data.json.gz | Bin 0 -> 225608 bytes .../timeline_signals/mappings.json | 9063 +++++++++++++++++ 7 files changed, 9138 insertions(+) create mode 100644 x-pack/legacy/plugins/siem/cypress/integration/detections_timeline.spec.ts create mode 100644 x-pack/legacy/plugins/siem/cypress/objects/timeline.ts create mode 100644 x-pack/test/siem_cypress/es_archives/timeline_signals/data.json.gz create mode 100644 x-pack/test/siem_cypress/es_archives/timeline_signals/mappings.json diff --git a/x-pack/legacy/plugins/siem/cypress/integration/detections_timeline.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/detections_timeline.spec.ts new file mode 100644 index 0000000000000..2cac6e0f603b9 --- /dev/null +++ b/x-pack/legacy/plugins/siem/cypress/integration/detections_timeline.spec.ts @@ -0,0 +1,43 @@ +/* + * 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 { SIGNAL_ID } from '../screens/detections'; +import { PROVIDER_BADGE } from '../screens/timeline'; + +import { + expandFirstSignal, + investigateFirstSignalInTimeline, + waitForSignalsPanelToBeLoaded, +} from '../tasks/detections'; +import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver'; +import { loginAndWaitForPage } from '../tasks/login'; + +import { DETECTIONS } from '../urls/navigation'; + +describe('Detections timeline', () => { + beforeEach(() => { + esArchiverLoad('timeline_signals'); + loginAndWaitForPage(DETECTIONS); + }); + + afterEach(() => { + esArchiverUnload('timeline_signals'); + }); + + it('Investigate signal in default timeline', () => { + waitForSignalsPanelToBeLoaded(); + expandFirstSignal(); + cy.get(SIGNAL_ID) + .first() + .invoke('text') + .then(eventId => { + investigateFirstSignalInTimeline(); + cy.get(PROVIDER_BADGE) + .invoke('text') + .should('eql', `_id: "${eventId}"`); + }); + }); +}); diff --git a/x-pack/legacy/plugins/siem/cypress/objects/timeline.ts b/x-pack/legacy/plugins/siem/cypress/objects/timeline.ts new file mode 100644 index 0000000000000..bca99bfa9266a --- /dev/null +++ b/x-pack/legacy/plugins/siem/cypress/objects/timeline.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +interface Timeline { + title: string; + query: string; +} diff --git a/x-pack/legacy/plugins/siem/cypress/screens/detections.ts b/x-pack/legacy/plugins/siem/cypress/screens/detections.ts index cb776be8d7b6b..d9ffa5b5a4ab2 100644 --- a/x-pack/legacy/plugins/siem/cypress/screens/detections.ts +++ b/x-pack/legacy/plugins/siem/cypress/screens/detections.ts @@ -6,6 +6,8 @@ export const CLOSED_SIGNALS_BTN = '[data-test-subj="closedSignals"]'; +export const EXPAND_SIGNAL_BTN = '[data-test-subj="expand-event"]'; + export const LOADING_SIGNALS_PANEL = '[data-test-subj="loading-signals-panel"]'; export const MANAGE_SIGNAL_DETECTION_RULES_BTN = '[data-test-subj="manage-signal-detection-rules"]'; @@ -20,8 +22,12 @@ export const OPENED_SIGNALS_BTN = '[data-test-subj="openSignals"]'; export const SELECTED_SIGNALS = '[data-test-subj="selectedSignals"]'; +export const SEND_SIGNAL_TO_TIMELINE_BTN = '[data-test-subj="send-signal-to-timeline-button"]'; + export const SHOWING_SIGNALS = '[data-test-subj="showingSignals"]'; export const SIGNALS = '[data-test-subj="event"]'; +export const SIGNAL_ID = '[data-test-subj="draggable-content-_id"]'; + export const SIGNAL_CHECKBOX = '[data-test-subj="select-event-container"] .euiCheckbox__input'; diff --git a/x-pack/legacy/plugins/siem/cypress/screens/timeline.ts b/x-pack/legacy/plugins/siem/cypress/screens/timeline.ts index fbce585a70f86..53d8273d9ce6b 100644 --- a/x-pack/legacy/plugins/siem/cypress/screens/timeline.ts +++ b/x-pack/legacy/plugins/siem/cypress/screens/timeline.ts @@ -14,6 +14,8 @@ export const ID_FIELD = '[data-test-subj="timeline"] [data-test-subj="field-name export const ID_TOGGLE_FIELD = '[data-test-subj="toggle-field-_id"]'; +export const PROVIDER_BADGE = '[data-test-subj="providerBadge"]'; + export const SEARCH_OR_FILTER_CONTAINER = '[data-test-subj="timeline-search-or-filter-search-container"]'; diff --git a/x-pack/legacy/plugins/siem/cypress/tasks/detections.ts b/x-pack/legacy/plugins/siem/cypress/tasks/detections.ts index abea4a887b8ba..c30a178eab489 100644 --- a/x-pack/legacy/plugins/siem/cypress/tasks/detections.ts +++ b/x-pack/legacy/plugins/siem/cypress/tasks/detections.ts @@ -6,11 +6,13 @@ import { CLOSED_SIGNALS_BTN, + EXPAND_SIGNAL_BTN, LOADING_SIGNALS_PANEL, MANAGE_SIGNAL_DETECTION_RULES_BTN, OPEN_CLOSE_SIGNAL_BTN, OPEN_CLOSE_SIGNALS_BTN, OPENED_SIGNALS_BTN, + SEND_SIGNAL_TO_TIMELINE_BTN, SIGNALS, SIGNAL_CHECKBOX, } from '../screens/detections'; @@ -26,6 +28,12 @@ export const closeSignals = () => { cy.get(OPEN_CLOSE_SIGNALS_BTN).click({ force: true }); }; +export const expandFirstSignal = () => { + cy.get(EXPAND_SIGNAL_BTN) + .first() + .click({ force: true }); +}; + export const goToClosedSignals = () => { cy.get(CLOSED_SIGNALS_BTN).click({ force: true }); }; @@ -58,6 +66,12 @@ export const selectNumberOfSignals = (numberOfSignals: number) => { } }; +export const investigateFirstSignalInTimeline = () => { + cy.get(SEND_SIGNAL_TO_TIMELINE_BTN) + .first() + .click({ force: true }); +}; + export const waitForSignals = () => { cy.get(REFRESH_BUTTON) .invoke('text') diff --git a/x-pack/test/siem_cypress/es_archives/timeline_signals/data.json.gz b/x-pack/test/siem_cypress/es_archives/timeline_signals/data.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..485d9868efd21af89ca7145386c7b95142f17205 GIT binary patch literal 225608 zcmV){Kz+X-iwFokuXtVn17u-zVJ>QOZ*BnWz3Z0SMwTY}zn_9feSUO#L>hs>RcFmw zBg=M`yCh3(sa)lGrEB!=Cn5ll00~||0wi~4)J$6var@%B_ZR#2 z@BbJKo@Ebn{_Mrz8H?$&=kkYpGFix9{w@9?{uwcOHJUO0c{nFo#*^6#vS3jbaFPwb zQqK&E8|0m%yC@(tGDhW&e3p%Z zhm5BmpS=*jL`?ko@mcZ9m*>lSW+WTU<0PxymS#ybyQ$r`^B%_2ED~>u;@R$xR&U(< zA@>||(|%kjPsG&U zJt)OJd-saszTNkzeRa?G@_Y7wFTZd1Jr8Ndrz5rZk8WeJ92fH}n${;*mmAc#|sas;A-lgrw=o7b9fJ45~%1lxHM@emZn8&>cj3(rx zjDOBR%#wne62=7AfFVpu$e`x;3N+AZzM}!)W_!U_;7l79Pe}wr>=cM^cs!y}_Amyc zkW_)kvn-m4e*r}=UXnbFqckoKj9}u2*!Po|uFfLb;ubF$&*Mm1o=VS1IE!!%ct&o3 z;qJh}tY3ft=RzW05dlG6^?irr-cZ90%Ew_1IZ#K3eXW4Q6B=SlfXyO62Rv2S@SGnu z(8Ke9*lYqoH;8SG06PlM93s~7gY9^Tt`S?>0CEff*zv1yp?FHHhra^rW>7v8wdi3$ zjuV?v&%i*#bfKuW0Hhy9wE@taDK@af@u=8<4$Q4$JARl)1uz{fwzL3#rJXF`CnpX6|XoEjBiXE%b|0oonzq9bSS zW%_p-v&96Gw1|`FCK9iO1bLCs7|3y4ju=#AWDYrr(z|g=d1d}JAfDDB_htY(~G!i^bK`28x-c0mTusAlF?IL{) zhmGcNkB;%Z09eNFqaF?h`@5 z>7fb-t~^i~O_>c0ae7M-JjkZ)zyoa~6AtKT2IW9r!JWcF3rPV2z4!z)Dpq*CT#%VT^c%qEcY;mM3 z#YIp9+I$sWcxwF$Hay+Ff*qiOzkwcJze7{?m%!n5HAJO<9XzaFm;Zr<7>MSdW4-?9 zScMZxR!#*L)^v^2QAnoI1co2Z67pg)fnj*4B8FphC{f?>WX8Mi={_OD$^TVF3~y@8 zCnO7xb*#S>Xh=x_6lO4nKZSNNKiXsD+-B??FR<*kE6{M#+O9AI%V*mF9M~=mGlT6q zbV!5>V$RwXa4^BvE6Cs`2gLmk*w&Y2^HIW8;<8Z?vj;#$zc#T;ivXW>-}C)UnQic) z&K{T(XUenN7|6z0#hvhwCkYV0=mL43w-4w(Qw0xkqiMhoZl@{R0Ceu88Oavu@#e6L zpoeq}G>LCUDswCxwDHXikWE~|&9mN&l;`>+Ix@w=xu@|ua4>AM3Vbnxld*7x8%Ta6 z2{?U7#UBU5JwLQjNN6;PvWMdnD_&ydt%C=(`U>##B#ObL?5W@`Qw@QfF-!1ZX3UId zpW@_hMCS8Jbb_PVrEtU1t4qW*o=z7t>Awo(aI*xSr*wffLBcrsL=pz0RzL|l5^o)s z6BJNqgWL8X)%#syPU0-4F$^`e1f3;hmL6TD_+qG`xM##c%9DF(oCFsfQHKsMKw=F) zz#xgn7QpO(Xu%RS@G!d^V$eiW1K{;OsNjhuY5;2Z5-XIzge72j(*ah1LJc;UAcb|* zaEz!`wX-vRW^3&y$!fD6m-~{)or~(gE8NI=mB!dp=_^ zuwDkW6q6e=i~dlw7mB}h4KpACxegnUgoLGLgVL_SDb=uaX;3OOIL#TF!VF7Kmi9$* z!{KEHD}e`#Xu`%2yPV!~dY3L>OzRRf<2h1jogK~6j7%o7ARiEZvWA==r#PRt5JHK0 z5>Y-&Vf8bZlj#z0FUjxw1gyfVjxH>DDb!#JBb0!_oWPWTK?(09mUSA1zI1b(Q`RK` zkBiqpn9K!i>5NKdY!8X~I|{s0k>@>F9(^0OzKzE6_lLsCP5~4t*^e0Vn%# z0T@u7K(GldVW+c%p3D+*DoenLEFq?`1fIkaa0*K}sUU$Rf?TG7%m8(+M0<2<@CzwY zkP^q2kb!k^e#pxc&c^W6)-0ZnRarNH*i}(rps=|>JpqS$S%DrDg|9;gN8T&N+<{K^ z96XQ{%}wCY)Kvvt23vvy4RDIU+zsJvgc0QPw4R4xJj;=Su}tQ0p;#tYXyKU6a?GGClLcg8 zT@2JRnS+OEnar_+vrJZC1F}q3P(!m!HbDnR-ho;sH^4(Vp5FitO4--2TOjEK6x>Oql3(*Ai^7OPaVThpJ{I_ZkcdhHKvlk2#|@_VMFVgs z^)D*WqcmN>+g<)eFf_=sI2)5NJF>6On{aUrcEH2<$m**X!=3waT47`;-zrcm)=U zW3dGLyC6|8vX@J=FnypU@|4PK2VmfW^w*ZarP~=8!v!?Ya$qjy5Piv^I+4Tl9*5^P z4$)s6mZLZ%4{>0w;Q)QYCFC)=kw$vPVdYb*K!=DK*kQmXaFCNcPDde`MiU^Munru~ z@!SS(sFUSR&@JA5ulElemej1{hB{g16Ox5-G6e`7l9jW991`sN#bm}45=4_Idw^A0 zaSi%}q-pMm1+(w_tP$DE7P%EZoSm}X1U_5H+_*sJ4-ocT2MsH_Z5_KbIzdUKT*sbL zG86w4qH4xs7!G~w4Tuvy3P^g~%sIE!uL(S#-A740lg=1N67FkgMaHLM831koTx~7o z0=xJN2f}3m~*i(;uChb=kVD){GurrWFz9~D4L}ifg(NWBwn!5Jc*^JEfjSn z2OUkt^o0Uh+gx9B3PwQ~ z<4hfnTscs|%O?>P%n*LOlm)p0UzOwu7Za%6zfzlEqgN^`2>AbsC-GfG zM(~U$b>u(VVfDP+3Dbu(<5N(bUV#m^zu`^w4e+q~ zJ|*{@f$H!aF~nYmH@U00f%P~vvQtA1hV0Z(10p*$+`!0A2^&;Qz_KzXkkmDdr&%=1 ztIvZ0tw<#sO?jG<8$Ql)z`>pJ-xo)_oS)lcb%{9zW9ld%%UskG7G?=0a3UO>~Lt@I&^5lv;YppgSv(~0l6Q_UxCh&V;xa0E9)~3 zBQHk{^%SIn0_I@3K+VKQMtK5%aImLBi3O!p6`c*l54HxHF?c-1D!^Hz>_iQ9N@f`umFO-q2NGI$-e-~^2IEIC(DcPKts)wX)ifr`v!iK zkXaT3sry?6&Z30FBnI&u9OMj2f}N^Je@H3mAun(56I=WT9B4qPo9l8No-Q&E;ceFP zj1L}aV!(q8qY`utvI!3|1_v2b(zz<|$huKUfprRUPE#^3 za)p9}J|oEuJgsTQKMnazehlD=s{H#nAoOk$-;5{G6yScyB6wSiSfpcE9v3-%j2SF9 zsB(dh=kSDPJYit>m6!l?;3|6@9Ogjf^oJ)kLr$_q0&fevpAKpE864~wqP;iebDjV^ zM@u=pIH;v6o5+s?!!1SSjKk~iG`ivUWAWcv3=Vq)5VM#kV?GPxghoJT`8}O4zyVLl z3`knq8ft(Zbc8X0Y#}6|9O83PIhoxJK`K>?;9uZClV6P?{tX;#s?ytlgAJ(Ea7{ka zcnWYM5jrU}jfICgp3Vupc@jq8APZ1JVTC8!rzt#A!$2BY<))o- zXjudb-Y%Yt*jQE#fl{)$Hen$8Fh=vwAccGc(TpP|$UKQNfX7n+nOOvp1Iz6jpjYwz z6y%A6a&~~H1$4vt7U|VV;0Nv;1o;`(?G^*mi0}eJ^4*@w*1TbiM=$7g>NZ+GH7KPwY z()26{YHj(A# z!GVtGbPle%)^gLH#1tMyQyNJU!&9XQ1vtOq?IS9F9G=F?ct{qLYzS2+Q8kf3s)6dv zM=<$0Nz+dt;X_PLk@5+r0xQ@FudGw|0MAckopNxXA-ZGUM*w}LmHQVwsjuu&Py<&J zcrMZ^_W;QLmIdMA;p-c|sCRAm+V^W&o|+_wYEqbiIS;y{kOJAcpbF z-2`AHfP@Xv%RA-2156tOl9c@(JY*ne2*{{P#oggab*XfNOerKcK$vb-%Gv;r4l|G` zycLNDRxv$Sw_}=3AUbKL5W};{d`^-nz>0SOMUHe@8&3&90uNE)R(c6M+oe2GgXn#n zaFPP7&^L)vcy2^R475v8@l6E@1I08#$~>5sHX;7OYNR32=d1xbV9dYa_N zm>>^)<^VCLP(5QZm>C-(9vcgZ2@dl;z&hm7^af@j5wT?h4ly4?oGa;qQVwwc%RP8u z^7v_d4^SUW1s~?w2xLyx0(%P5&`^Mfj2&o6`*O;Y3`Q{E4UePwNNVEIjL))hegO{f zD0_g0S$rjmXV6fq=aYwVl*VH)X~J^olbDh$I`SY~ykb0$BMIPKsBcMnI|?S`j+?>Q zv>gy#T?36h3m#}2nQ%a-x5P97b+W(=MptYjkys# z6mi%H9*ShFfd`~Xuj2+eSwLyl4agzxE}%5+P2^Db6-b(QBX)>$9gZem*a~2&T8xqZU68&+cbyy}Pp}hp@IZjwL?yT=<1~YkjbpP3P(tk*X3cQ{ zu=26XfsRvEt_kpB6)l)gNG7v_!)*cV{s-h`(}@3`C+V@4{i|re9ZzOJ(gxJ<&k4OF zHyko~DVqRu1()c-u7I)u2^S0`1v~;0A6)d4i1Hca?vG|^MkW)8B))7yD)>7*zPLoc zm`+IoP>CoTut)$3U}a*4DY_JNC~+8@$e|=x-9*kJ7~ue$$kSUsfx1ZLf5y=)FMb75 zRm-P+5-$!vC%GI>6?`5iY?SvM$i7~-VM5YuEP&2#jy&MsuHBT6w`odw!>TRiFU!Up zN(IXw`|9;Wp!PCDdh1ttt^2O+3vNo|15dIy;4Zb=-=01Hk3sRjXHvocKH?Mhqxi zL|%I4j+~LP`Idx-JmE9SQ*qO;#jn3DFUtnWr|YjHqn#KoY zzrg+rghmc_|CxWa_~!DJV=*4`%9sE6@*n>pkuR^v3-ab?YP6Q^dKNKx^*%}$WD@C$K@Sgo}U9(7)``ye>Hv^O}PqYZVhwm{Hzbg!SmA_nb`j4>i+dHtqeEg z`6f^dc6GfrHox|?oL+0aAzvc4vb;~kp7E>r$L|X+N$3ml*J)mhQT{decAmy;q4t`} zeWl!0d(?98ncpVrFzU;fFXCs})%jCuHLX9zqEzl-)tyar0FhhdY%!ULf6hrlrfI7W ziy!ZJeqSBD++O9z-MD9#kC(ghPdxmw+>1|`VL6`vw^ZEPy_b*?5 zdtMuWRZ|tBiO^pb+Lb^M#Imw(NB_Mx1k!Oi!P}Vt}5--+lscNxACW?rmy_nf08sX^36wh>X4F zH+;sbO%^&&T70WIBB4|#)H|!r19Tzg`1G}Gt-2ElG*lEFS{f*l#f;{| zgOunjr1DbiO_U&f7pGBfi4@?H=;k(`QB^^?Zt+k}IEYF&JLPxGo}aIMK28`79NYXa88&=D>d2!<@&Um=X(a=E>e=S z)(h%N+umP2bZqDE`s_yE=eW<*^XSp&lexsrEjNR|2ofI)nKeDHVtHGBc0;{Pc@pvT zUHQweh5hVRl+a04i!2mGr8?#VEEz_jqE@xF$x=Wm+cQUtm<&$cnzx*7f>dBwWe+^N6!dBXrD?!bTmg??JoIJez%$E%~C%QmR)H%Y|GMYS~Y(!wzN@!5ZJUhD=XGBsvZvY@=5WuN}Gg`N~6 z*}mheQ)eclRwg-=rE~Xd9%hwEv1O2?YF*f#E0eN1Y)k1`c2p7qoVQN=<8AU%V&tp;nvlxoq6XcT9qf zA@U8RZQPHX7(HRep>5nx?F>~p5x*AO>=A12M>&;0$~jmWL-~(X6>n3273#@iI{P69 zBURvmoDm5x4(eWre-e4pCMMDeT5}PYwyrVfFg8#W)2<3b{-pE+p1jKk0hQXryId;% z6o0A;MtS9p658p@?B!(gS{~b0Z^(pNGWlL;Be}F&OqXiU2YKb=e!sHnN$FV4_Z^3& zO%CWw>+*?~*jj$SYdcpBif?UbPIC0W-=-$5ch}!kKGMN|G4hc9X>W&AvzLmmyxnYF z88DeQYf3&>+gw+oGNF0hM%nIW+XpL*t(sjpG92oqa8P4uEH&^G+q+?I@20&!R~!mj z_#T|E-Bv&CR=fNU-|lU98Hatg_8v}zTD4aSiAB2BT=77v_V%;3(AnC;hG?E0g19%T zlWPtynBnn&;R_glasVZ{IW%Nilba`H^;u4m%EZaFy85ILKi71Y`e$owq3Kd?K(1dY z_Kg*~-zpmE4#p<82JxGr%|_a6q|HX1nT?i;St)35qnq1_JWqc)shntD3)7aG#@Y^5 z{rg}`PLk#3@~raHZ;e|}qy6d-f2az_-jKQF23_pCZ4bLT)le8oZ-ba5?1dR{%b~eH ztJ$$X>+&l*kL2EpPP>ozr$HPR-8%STm8NTS4f}u3hj^uPTe1D*n(M~d%OgI=+qeDq z?u)uH0bN)Q}51~O4v+aXv!vugzYR^HS+06V^W@%}f@*#AY*rM5#*eQeh# zysO;TJP^A9Tzo9>8OI{8B-NS_te)C667N^HZD9qwzJBp>u+F(A@{Gc**F@#9ook|U z-QI)w%b+|NYk>u{fEmut(`R4uhnc_b9uw^3sSw4o<85MytY2Bj!NZ>^2DFAHJ14EQ}J(U*D_?^@M*vq zlhffJD(Bbyz%pK^gz37nB0-eZV0L@K+{z(9j*_e094TSf1VXM6v9kDs1U9tmN`}?pR!Xq|lv`c;<`+$YgYLiAs z?9ynL5J8*!wCNNGt)tYJBerU^OOPOU)ro!q5tp*Ww2p!39szNeI6>Ya5ZkTiBSZ?? zB~#E!sFYLDIBA@Z5Gu0cH`9Rs#1&ImD(4O7=M5+3#S!oF)VIY6`fj6l^|U!}(lyw< zpNxI^oG?uoFfk0677UnnPcU1i-(PD(LFAk9)cw*A#1jMtL!PTFa%jIrt`QIF5RZ#Z z%$R?ug|HEi*&!b8o2HG-lkngU@q~_Jg+Y!7ABo565KqhG(T#ZQ4)L^1XW59y=@3uL z3{H)B+z#;=Mo0{nj~6`>kJlw07WjsjyDhRK@%UZthn{CM!cW43y4;{m-}VjrL_l5c z(4NUGhttylb-6_cVu4XRpF(`U=W8>dF8An`d03hOb-78mjDKtf)a5SS(pk9~(3Wkw z@OU~9iA5>3gM6%A4Z8T-W`N>~R9@6ys~$YtQX|vBvzI3?*AqNzq7n8n=-}Bd z{Vdu!USG9~#p4N~&3#>Ti3nXH;*d<&YO;(3-Y9z*Z>b)YoZM;$P4&y-)IB}dUJ z0%#Qhh>1XJGFp?lTo6H-$+oE@#_^ob3K80RAgT|aHXgfSYz#{!H}BPk6^>9<4oA z9zIcf+zCT#k6mkzuT*zy?NMuw2WXG4inZCZ_PBFSo=JP;fysi93GLBy3IndsOf)nC zjxEo19qv%AJzkYsrp=RDExSs!?1~kD!3WVtx=7m7E|NCm*{3+U8&xtNKfk_=zFR8; z?4QVeC&|P?$eDwbvf!RoS)=&cF-exwXqWt-?)H4((LsLavWw zEaSP$GPc}@&t$!EJ?taP(fY5}f3^Or_1{OU|H}O0$5?NUDAA~feZ5Mfs*iYWB^tfw z7p>3;&H5vg(64Iwb!_$VPPO_h>o_**9lPfLnN$trx`+{?RECNCOijqaJ0X{~zHwzGp`j@pY&D@qbJg+P>mAtWN%1&zHJnNN2t3~>uA#LLt$k?i zLu((8Px~l{UjE?Vhj&{0(AvjI+D9(uM$sIU+HvSIIFs7Jut^Qu(rSlRJG9!N)s9E2 zc2wD();+ZD(c#GlOaSI^z)q@pct4_4mWWZAzFPQ4Vis z1yf@`zIFu#k0`Oavw|r)paWaUjUxnys$kkxLBT@3Dm9O5tti+F3&P(UsZaUEa~U=#Wn8c|g&jGPBU`szb$`;(ga0I%Mvi$-SXv z^;oScfL0aG3G<3l$7_v7Ycw5Xk1u*+EMA{v?eoVsJ$~Y#?18c|I68;?iQ49S+23bQ zBCFL+AnN8u5zBIMcILd(tVZsflxK_1@oYwP0ZXk%YCUpr1$yK@4JMw?PtjmjkDso= z?1FM>4W<|EQtS9yj})_BtC3obJWP!&cF5k<$nA5o@3I0$=sO4n%BEX5xA-m%hL&pu zoDn}n$k$~Bu0tWazOn+#yiWC>s~SW7N@)(5N38jRdfD;<%whvtpV0LN&Q@=r6e8c< zU$ELh!Owa;=J1hgc!g8ndF7No=C}fJ^>oe;v`l&Oo;7dZ55A33K^cOD3WC&?^BR-n zA6YrC>Ybug+h~K~o$PgTe5~&}2Yvf~^Y(oqz^YYo+FQca4$JJFDJZ(^k);}W`A)&x zJEi%Q;ILicTvjK!nD_Ndh{#jJJpCtdwXSAWvgpLF%7Ggp6Vw+o+1 z{S6Vrj!m@stJPnv{%ZC2QLDf5^*Srzb=7}57UYly(Laoz4cIzv&3gwN8sx(bMkh4t&;!tmOHtV zjPXaNPVOl0Z>bzyed6Di*%OOr`%C=WGDTA(o-PyrwhZ-e#M5Qs-s{%x1o zwqFjpQs`ha=or}Y7IcL&UQN9(+{ zIzz+(kwdAP6eG21kBT+AFUf6wSMND)517a2iV|U=PwkvQ@j`7d>~Lt|AhcZ;5?kA) zACKB_PMFt|n@nprTD$2Y$1VRH$+D+6<0D6-@%dwi6@;WZYtaZt2(}Pt||dc$W0uoqdl#TJ$`jeAML68wbuB=wZ?r%dw0={t@nev()u)S z`OwivcsoA3(fK*RXRHvV3KD~SN>UwXfRC-c1H%`K@SNYy`+_z^opGnQM zxa%4y_w4kwn)%4pOs&6Z{q5vo(Uo@K>G=ooLC}3Z%SLVs)pJiscX7YQHbhfJ$atOQB zHgn~JbgX=|OCeW8Yw8Sgr)H4rB!yCc3FOf8dV(?M2z33Wk6TAqWxwTHFRQ)ru76RvBu$3 z`CMm}LFfe*RVt^YRnAAQa%x>p>vB)VfccK3=_j$r4?c)q(i+3l));D$8OmNcFQ&&R zZw4SG;-HCrCj9{$p~b^c>knFg(E5YcA0Ctbpt#y9#$Tu6(y6#~DlVOhOQ+&GZz`^q z+i>5BxE$Lfm<1P5cy%H!_=&hSY3L#M)TrvC%-^NeXq~pJ{9j*byVeBBMRInPjJL-V z88@^%qi`b9Co)e?PU#aFElM8siHxp@s4F7siio-*V&!z;s>&g@OpbCb`q!h>Ai7JY zwv<7u;85Ga?OyT)q_9OrFfdtjPVEK@E!&hG|8<2kWl^Fga z$K6{2=_`ic+|01@LwEjE`xntVm9^|nyg`eSD zLuwngYq=&iJa75@>sV%{TLVCl__86%jJ+$9j(UNLF|I#PxbG0h*-M7h^Y4;atcjGb zy~Co8C+^!Dm7(78K9+mp+8cb^C79<%a(71>l^jKpZLt1|Lz5x?Dc{>yfk?=#%KG}| zdDvV&L#oF^hpG2ek7^3(Jdda5c|=lUt)^qUt~`(1(0Nyp=W!j~GL@Zq9hn}t;%k*^ zueVH(egO}a_>Rg{*ju88QO@a%OsC24flTs2~7Q~vm zcMtc@??3&|@dcOt!hgJf|G|6n z_UHNRd&mFFEctu%-_HN~5dQK0)t`U((Iv^}iTC51|GA52_s)O6x^qAL{q@)XGnxJJ z>3{$4%~rnsG~sVIANO*VeGrPq;Jq5~f%FcPUUq4np~=Ib zbr!lta`(MOJfV>0R)u@M?%DEN{Z_?g_uP}jQ~Bjt{AuVLYu}2dq90`6ZT3)QMXk95 zkok1@)i6uQEX@~9-2yw=;mwc8Djs~x>pn%ZNqkdW+u8>umsfUS zN#)l(c*y7X#Yz?`pJCK5ZXPXEdKFEpU;R>hGG1i!MfSsTTawFQSZo;ZD-y%>BosNb_ieOzyH5~X+VX|5UD^%f*p;(Z;mpBe-eLM6Gyjl3GYOl70aRd?d8=Eg;u|L zLtM=AW;yu#=CE(7`D>0b^p>;5gs(5@(w{R|vC=JGHO0g114-|S-e#ghiIDORp-4)3 zGW6Vl4Nb;eVlvYa>PL;%;?8GJpFV32} zz0?fq8}ng|XH)aYh4MjKhZGZNWVvRqemoX4EYA-2o}FKr9ZCD~T!SAEaz>VMEmpYW z{CK1kYU{_deCAj`o*f^3uKjqr^5c0agr6*Q^0&DZtU4E<&IR~!mmgBiAzmq`3pH`_ z;IK89ptZRb%?6A-tS1j7_curSF4YaF2TkNN`JHf1e3LMxFSuG?(E5Vb7qq_cIP?YS zS=1_W1A6?mYOsQn>L_d-g?&v?*c(&x`eU&-mBfuk=uqt)Ej~C@`=EWg?*MHv$gW3~ z9!$@BZuSHMv{^{G891tQw~>r%(~Mh0Zf`Qp<}mJR{?SJnkFAwy9gki9udjG)B`vQ9#Dfo`?8{g&EUhx|*{o3(Ke(gv2jqmbnzr5eL z)1BXVPOq-rZ=8l6AqF{=e-+R6=Qr*%=KCne6C8=BOTY1!ejSZ?y7U`wX*X)b)1}|I zk9@}@Sm5yubR?cG{l;6KCp6;e#BaO{Kkb%&<6Esv?ftZSQMT(A(3d|O+0XRGxk2xK znME(>|0KhEZSg$O;)y-6mpjIg29^p|aEHE!?V%ZB6ml{3T^wwmbUD0j+xf=y-#Xon zG-{e7!}PDjsCi9>HRVV9UOiL1d&^)|Ty{2#)qEdK_&^><-$=*Xy*9Xyvil_y`?pLF zqWq7SUM%uAV=$EN&+=a%pCvcJe;Ln_VLi9)KdD2f&OLr^$l|6ry(v9pDo04_>WA_b zZ&t53#SuubtDL^{>P92K8Y&%nzlMaeO9jcz9w^%+_^s=#y^Dpc`blv`VnY1D(a z&-v9wWSp8fvRPkjDMrqyIR5?h@Ryb1_$t+kqgEWX;y5^2ar_X^2eC{UampE1$C;yd zdLVB+c~G9|b!FrH;%t{tkZBf1Y7`np!rSGQ3sluSc!Hc$7`$iySP6q~|E7h376w`v z3_1}8N-@;J;KIV7P|q8L!Jn5`E+h;Nnjq&C1_t}rN*Mh4wH5|i7+kk7sGb45C|Wdl z`_rKIyBIW8xPhnRY0M(AKQK5#q-+#;DN;GCgeXSD(!Xt#BJauzeV#Gxk|KxAkTZ&r zUz~q^T8WXLe$iq?i;?RVBWi_9)5D9ejnU{=6Fcs2Uk`qK`(dE2$S!!1K1?Uk>~2$X zOcs=v&KXxDI{qFf6E^s}SpIT{$u|UL40%NURr@k3H8@?J=v#%);ahc}_tWw_M`T)h zexW=|YBfbO^@#>i+AwK1qUTSp4ObVS$F7qzic@m$yTiut zU&{6-b)ao*`tq4$W7Bth^!X|_y@L7qmB*z6KD~V-&+Kp&aG@j_1OyAOlDFE{ZWhe7@Lrysp#ol%nw=-=2% zljTTjvRXyF3Kj8Ds4MYw8qWsu6iaI>T3gZD%Eh#mhJ|=ZWo5eUxb01O;X=wv`wi=i zx(XeC{^v?pnQ31Lt*dBVWo?*`(N)x{R>2X2_lxP2BoBjc9`eLP-6$)|y;1%{CL1jN znkVEeGcDzno@9ErDB(q%NdDuOle8CQM%awm%VBJwC=LXx7!-tD?!C*$5tSiG@A3@1 zKgFM_f;5XWGWmWnqq#6#OqY`WgS@iZqUBFwkRzJDl$jx4^ZSZKZXx8Rr?xn%d!4`Tfo&i)YnAJ`=9t+&5v3W*B+E_eY@El zF=R=31}wW@#;xs;-|>7bGc)dNsePd3?C6DjMj_5q>${Z@|MasK;#!Dbw-B#6E;2sh z86;=L0Nm3cy-KXc4hRL>x9l zdN16Yb%E3eWrjb%0Wbx|W*sEVnpb$5(Q+}hKp zILGY;@_fC7OWCOBSMDjNE4U1{RB)+p{0+5S_UI0M)O0D7#7>3Is-}zNB>%YkS0zKw zU*Gjx!{tppi^SB-oraccEDxbfM`zibj!1)0WQm>6!6r9 zTo$Q07@o5Wo_#vJW%pI^xh?RyyYM-uyO*{+9AbM}L1u%x&ZMTUI^V z`~4k}5{=(?JO2I-@5jdPdmVp&hvP=$_x-NFzuhX>_eAzSf2d8+7dv z!uU!Ix?4}+)kI*UH20z##p)AcoM}8`Wb;hSXnPKCoOJZQ?Q@mW_Pq_L9>A9-()oPy zu=?jU9mjW5U-}69_%{OT;J;?^Y{=*GC^8|FKUELA)!&%*hCay~x*CAg-W~cZ2K%wJ zsIM9A*VdSdo_fA%z5nj>zL1_CU7uUFq1Y$pNi;2YiH#Btj3qoxyY@%e$gkINlj>XF zhKEJz?cHIEtgS7oJ6N>XV$S4*$BE@(7c2e30j|>77WM+;;Iz`3#Y9f?0-Wzv z;p8L4%E`&B(v2NGAjw!|Od2PP$+CiOx!Q%w78tZPyNKfreH@0|=hXIXqgXa7mC^P$ zIn?u!YaQ|?nF~rL>zT3buk-D|F)%yib<#~{yrb@{SP$dE5VhKya$}gfBX3wF^yg$; z=8?)JnHt3cmn==j`n4HCK*a*OUtxe(a0f-cFcXRDUVOjzS(LFCmAOK*iF zA1}WvJ0ag&%TnDhWclRcNBP3>yg9lplr@&Ktk~dZi)m04N31sh?QX#HrAB3pY}Fd| z&FwF5EIPc@O>63Cv&N9uV~BI{v97OH%Q57!edFeW%~GEkPs%VoRQ^&_&PK~gm@YG< z-I7VTrBj!0&7Y}F*_Du#i=ddl8@+7onI;tlt1d9xZ+2&rlEmYtVcBZCfPS)j!AQEt zCcLjTnbo@X@I9GEle23K2ZktbmYsh@bsK9^TMfo2l!MXC5v#-X(Dk`xN44s^rC$Bj z6FY3`_Z@rP(&b3UUc-#NJ||2B1EzVINOmD(XW2+*)l;x*-`#XP*?GNwsCUS%OY=?R z&6`4?@wSAgi%AAN+&*thTlc=oQ^)%F?fmd_h+*~5_jy~^MRC15f@s!y6qe5%I|e&G z`h3IHazl|g$3UPS2coX!)q7^fvt{MQ79&!9?ASrs{poGvvZ1oBJHPfYIHpcMQQXm4 z@`*wjmM(LLkib52O%zdmvgA1WWbfZqFj z1)!CKl2(`xQkV<3*GH%`xAZ^NI>m8eff`R zdZTj2ZJFKw{`j%{-bZ!qWAisZs;_=re)psNz{l0M%YQGwU;RO1_^42{oC`&t>>Tsl zW2K8R$J%01+|e}w+YF(2JWOnrDckWeu|wtDZsCr}*kPHo%er@QILKwrAmI~LyP{af zI*E2yNwk*=sxVr^+mtcbgw{N&N_gnAx-r9f6tm;)g)pbtov(KsS zY3%mq26@keQQ~gp(K_9z20gTb`E;X3bDW;7#b=z;hSAPxNOcCTm6?+OlGbogJB(OO zyw+_F0K}gmN6fp|zVuY%)`VQ=;LpK+wWCJf zA2qV%yzOaPiMJ;CjMHDg-=s+a_#vdb|1LqxF{oibxHLRgm}2E>@k`IrJJ;00dat)z zQqtSM_n=RLesRpIW#BFio61m5oj(5Qr)MH{92=d%E*QH}M9qWTi@mB(0KbOlk!f4W&aMs-6AX{SkRi68WkjCnu2jJSOPETmg=J4j0 zf^FmHAFC8~LE{=YohAk3&gE+&$XA+2UvwN=vuu?1e`&QRwDH}3qzQ;dxAqPhb`FYl zg4|-IHlgALyPniBh|C24R7#)YB`_(`4|y^$K2dTgcQP?W1fH9{O+M%DJ>jvChn(yp*7>!e@0*C`qk1NSu%frT0=M>e}Ya?s_nR++f zo4zIc8%5Hki70)1F?;Fzz~PK@)6Mv~L|_Hc&^5W?cLB~cL)UMTX-SM%+?ch)KNdJ- zRekO=%aw-@tC&5`YVy7{E!e6{Oz;H%Oe?NjsQtXHoiSqQC+N>1GDT{Ffs{rv2-i8{ za5A{QoY<{l)d9K13j6;31Iv@Kn_6J>yK`Tm2|3v$BZa&)b+Q4e1cPiH$^1IXc|tJu z;(fa7TF>=Hd+lo4N>!2VdjPLcX+vo+3TyFRLj-F=yt!`oNOEE=Ls==GW{DvVDnGss zW~vcuIn7Na%~4!bS8`lb)DKxqm0u4?dGtsC5F!f&rrlRr>>Z-}&fQ|UH^7Zt^PxOZ zN3RFJv+~J53G`ZnzdhDqQwqvX5#QNVepBVX`gK^(MXLOxzM$KwQDyoa|GI}ll^>ak zL$|njdt$?T;>ATy48kTnb_ z&FV5*aeFJ0Hmz2S7;}viW`&x0l1gt!DjVS)^|AP_hO?RFh;t7P`n}*xa+&@j>7>4T zrpLD#Z%vPO5SRdG@9XS!xlBP$`6Jm=fCClcpx^ZY^V(bo95BwTLbd23rKLpU=5RX( zzD?*NEy5zLu%O!BeZn)9$O!?9YyOi>ZNZJ^kDdi;8=U71w=37T$K}}mFt8(bu{-_urQ(*Su0*7f*Cj)UXB*PRe z9%5A1`7D1_oR|{a2X=2$L>7+7t|kX2Ln<;cGl1WOkj?7XhFFC!o;uQpr@hm^W@aJ= z?E7m!i2ywY>I5C_;I>>B*a`AyFzo89GT#y=`!vTLJ}XB6=g-k-T?nXj`gb1Mh5uCF zuD&ZEq}oSOjt~^wu9F_Dt8ChGvLE&<_6?w(;cEzv`x!BKhleMn3_K2%#370`N5rUi z{Jl_9*k3)S5IiXC|B``G>}2ON(-`SBcvSJD|6Kb1e6H_Hv~>aqja+Ai@2scOtORs$ z>i4VfOGY&5=jp)qq8%*Y(rygq;?Vd`xV>lWQAUA$orEj&w!vtwbOc)UXZk)E@Moqu zvHi0Kr!w^Kf2ytF=XK=ylfHI*p1=dIacCW(C~PizmusYa{$;*BB%|WapCZE@zU|ht zSbEsUSZ#hX88Wxop{Kuuv36Yk^CHlt)ggR3S+~NS4@hG#@`T5QHNvcfQSv!%y*Xb` zyd0yeqEY=<9i_9OWhmY?zT+f*gtAkpx9>Z=I$c1IgjR`<{0cra5h?b7rNSoztF!M> zi%GhO+(_KTQzOOJM|iuC&62Il4J9OG5#pk&g6Ra0LD{2TfGbHOA;@8sSmm(Z08G>hSiGla!VqTQz%JVi0_SWMJStk=!s~11YA^Qkn zC(}y#?j#MEqKN|CSPS8NrJ%@kg!87t@uyz9iAXD7) zEumrsQPqiS=ijStwoW}uzmF(-5NvE0_&f~(!p!4!W9dRPcr7*=?>ZY7=}O8B`udl0 zZ0^%A{X&|ZbgFpAy>LeUoaAL*F(s54n6wCa;`{+1+cy_lePmPkc*bw+o+j4*HrTEC zLe9CCmi&R;+~JgK>3vywcer^C>-Us7q0m`{t@7~f>y_%@s{L)!9+mTspNHz#OMIdW zCYk;z4o1P?WW-*=nsLIq9JN_X^Y0$S10pEi#^K@G`zaRPd`#$d)(v2jp04Ge5Oj3> zA)EM@q*m54)~`iXu@Tq-h|ECf1-V-_aZ@YG3`2n)Op(DAtx=5b?$C=5G9+%00xEe5mklK|Gsi+G)-N}XSJ z`}NCA*87F78xzTIZbmkO;u;^B=mr|4Wb8j*t4CvyIv<6a$HXnyAE9XY{6YO3gCtE&gsq?qvaz3sweI%S>6a5H`zv)x4NT4XKO(b;K z63rb7@dbR1>GE%*=1Mnr@_u+hH`BQp5__boEqpQ!h+(hk9|s|@?q4Fm2x2~ym>Vu@ z$&y%}8Tvnsg!5K{FlndADIe3OTW*zuKR3z=?Hc;@4-y%#yT}Y)AcEy&zZH2Nrv?gC zO{AQZyFOeL)|(deG1=lZw)784uqtqMXH75jmTBcArbF>*JJkBp-CvT7Q}mEQ4-^lsIOm2d|kX zcoj!@?OHV&`Es`(<2{Y%-{&uU2_O0HIcUi{6@zK68J{B*r1yhWVO(;au78r6Uz}QU z0)1i9OrdCf)Rk%eFsJecMt6CWR%pm?P|cfvo>o^|mc@^u zoZ}^pEV`{n7mcCSzDJFXN6kJD-s@!Le#2nzSOgX);nSr|EwoSe3qfqUGe}GWg*kyz z4l3PRL;^7a3vUQ48l<{AZ(wm$$bM$js&Vsuv9~a}AtQ(}u^N0iNv%ri`K`#@!u4+=NAzIXZKo2fa>rI0B&$Vt1lX(_Tn*9R@+L zW}D{D1E=FbYAin&J#rr@kc)-|BfPy!u~&H6=*Q{Yr2>X3E8pyUn*s#IdKPc@E0IuT&64kGN^UNujDAXOd zt;*FNohj9a6>M(|)6!?xTdsIoLr{FQ?#EwO+G^q%bos`>8de!>HOIxNl{h2p6{QJq zP07r(-AK1oUgxU(mgHB32z7T*D*oNw{~;g zxbCMbZ13H00yq!T$+xOXFIodhVOEgqgqo2kQm7-w?WoleOnuJ~xCoaqnXnZBzGv7= zcLGXqqyep$TS`9;V(mEZ*in2c_twv<{BX3-vb%7SvDtT6gqe;vB*Aa!p`xXhPYf#c z3eKAMXI&U;>G-y3XyC^Q6#XIkc*Xp@monc`mhmTf`Fz-4@`OW@|GNwV#gLr-YC?)K zZ6Az1!*5&t1P944OF*~i$bnz&)LL8T6w=R5G7V*2OwF|SM2|r4LC7=ho%t}I z`90{pEB#y6pW6x2p;eRFG>BwtG&@Da+1M&-8+Mqa1*j8QOLq_gxryTL4*t#sg>L!(hMMzfP>GY#zm{!DNB#AeltgoE%`io zwu2m!qcmh^Nn@dG`C-&SuJ<~RKOzG7WP9REcQ4t##--n5lge?V-yWPB?>a`z-}X*c z@$-5;`Ldb&#(h>W+4Oe9SKlBu+V*fjF94R1{H8SB{&7;|MSZE! zL5urjx=wjoMDc;^#3!b1BCkPFasH-w7d}(a#FDD_f{%k)^v4z*X{7ii3?eZGdl9*J z??%{m6s2Al(MR+nvbu@a?(JK9+twgmH8st;iPP`b@ZYil9HNL`1kU%lemRVDszyI) z%vN&XkXeYR1d;UYj3?NHmpRG;?$YnA4;zE;S8WeHfHM;^g{mFEo|0lvf#2(a!s2z) zAAUhck!{erT)pil;XIs37-%LW1cjsfD{K-yPGln()qy}xteFXSIEUO+WRp;NH*Gah z#iwi)(blkAJpxf35LEscreN|s?s*=Ov1lg?D%#h@tkl9puXgK}iaz~g?e;!7EVh%w z;>dNDE#A3a@L>cfPO1>+bsUi(TEFyL>#f4bbyFI@pi-k~tdV$cDio$=45U2-LVqN` zefW?!)-2f~H?R}CvDRmuwW0S4c2RoD%a2^=!P1Y%+`X1>{TjDS(PuEDlcrL}lw~~z zkcuT?dI|#f5gUejL1@u#r-<$NCicV;E&t5L_xmxPo-VGd7QQRVLg~8`a!ti2uB+)8 z<=4xicz0FHJkU!9?=I_fKnnMe$iaC=zBM(89Qy4bHF>NTWCB8>cVVMjX=FP76}OB& z6u@<*3;L9P|6TTJMX4Cn64u0gwfw<_>Z)|F*)aXlx96B~^lLbQWRA5-&%jLLRIADF zZ*h)0*dNctr_TY)xayvl-_vi(jXk?tmBa7!slh${#joG2*9yHrd%#`c^c&%KYx~$1 zh(w$pPU7GSh<^sP8IgwONSX~{MSHC{(%0^aA&l$|vZ@9xH|xak=R{f3Gj9ogymoh)%HIqgF{yCt1UfuBjjkzw|rnz0YfT zY3phxemO^+6iu|Iz1-Cc7!lj|3l~M^x3Sws1DEmS0t!~6nh|h!sPx+e7m-GO?dI_R z^xXb5Kk>+tv>wXce~WBl!8Mx3;z?;7+r@ks59LE`x#C7w38GGP@98kV&9~gX4Fmd{tM@5wyN!?}Q7=mJl146y9 zWW&>;;AO)`sipcfe3Y=axRw{Pfm_ysCz)M?Om_w!kHe8zQ{)n&DXBk zXYFb(Eo37Pd~IJyQzjf|$9ePh2&augeT=djMz0|aKaXfMfie>#yW4BT4p zHAdh4Ch9mc^%D``?souJ+3Xdj{k6&s5yVVQ^sZzHsOd6J8$KT#1;UMpf6MS)k&9=? zbzx%$brx(@&TM4iFT{e0#bvoKr$;OO_vWqL30;eiSz3ptrwLk24YRT^IGB%hkf@K@ zm031A#bRxjM9zihuVF`ARE%`fZ>-lEgKvH#bujJ#_lmLo{*O6Ap7*sgqXHf2o%lSe zv58jLB@C^;@L*Pvr;bw5vO5~7%u}-zh9I;rNHuLl?U(Ik|Fgcv=*~ngXI5BbF54$A ze+1s85fKB;uj-g^jK~l|jMVDl7GhLVIB*1#zrxOU{PYL>j(~R;n2)U#d3iC*#^BJW)^lxxavHtsk2N70b1D)-!{g*D(Rz#5~14 zO;V0lKe^1(pRBJNgP(rOb}*XxV+bTczKM=Kb3IHSSGLO3cF^@b+pQxv1*chNjP9iJ zhn-NREQC!|+46sg6PHoR#LB}GgvJ&MXAct|*xW*BiAn!;tX$jiykOYq-l4|XN@jc0 z5>3mk{&8>rPyZv?vKW!eSDip(@5~VKgYYnM@_FP@F(%XAv_QFOLGDZ4p0kiNQ0$); ziM@UALJm>#-+x^r>BegBCNUK>5Q5ZY5Mig(L>ZE7O`3>0oOYhhw?1i6k!Z(~2%KQ&j-n}o@C-4`t;euL)<^R*d3krVwD2h1$kW<%3= z9yC8TM*R+yp)(QuX(66=PZvFiZrZ znDxtr7Jed3dChlehv;NM8gxz-M#RF4G4{xHdGz(p&E~ErMgE4P_#4bCQR;%P7U08{B}{I_p0JxB#=ITDUZMXmiYiHxj*y=W zM)jumbCnQB>_Z=QMR!`AdgV`&=)>Tf#qSsGYPfB7x%_cA8aLo?H^vhu6Vqz<@fRwN zBB+SHNL77(kjF;|hH>xjX{kr2;a9oA%R>*YKOkJ*E)dTjcJsPi{-JWna=C0T?0v|j zawX;w9yr66NBli2pR~dtz0#kGgK5lekp(uL$7HYd-Pz=@k$>gU`)%N= zxA#xmh>6|b{B5S6)XYV97TXtbuOxF)_o(A{AA8Zbi}6hq^p??lx3nv6LEA_qL;`;` z$UA{SFiJ590Fr&W#wh(yjX`AD*ZBL*IOm=^ehj+|BKHXFcQwg^n8JHRy{0007&$aZ zX-z#YOsGCWXvpSaCvdVY-ZqExqE|=X~2J-%F^nh(tY4u@sNJ(F3{zod1xa% z?)O#SqlA4+qS`b*>aYiKBh0cZY;TdRS`=(ge%8sY>}QwxQ3t}yX>q^LgO5Vn>U)L3 z5J!4-#14pqJZ9lsq6+tu;}R!^CVo<5BMS1h3yGDXXaA0svErOIrY{embRrO_uv}h1 z1%{zFprr~RUP}HG?N@wJE?d-{Q@n%+zgqIAl$IjBqptJW3C{G%5!y8ljFk8QkhZg# z?5qmOGVGJLW@(E%L zTaf;IEnImuvUBy(C&9Cb9(}W=AaK(tUJD)Jyra=wn3RM)X^~z0UT`|5#Aa|IEs#GQ z)6YaPS!}}f0p*DkX}{t39T(Ni8S@n0G)9wgco;ccE_U*M3&lmzs~QH-`4wY4wTNtm zPZnRT-e8peCy^mq`D^^`r$asyEFx6EjxLwcs00N{ub(kazxIJ(&gM_rf(FtEAJ`sl zNp_nBbm0lMg>NIT+L|(^jCC%*rk$pqK_l$hc>Uaa3mD>+d5h51uUU+^N+2JGYY+(@Yn7If^$TM7Sk-F32j-|0>b~U;eBcz{qu^ULoCKINIL* z0;bSFCq30DL9a3bbUGJWgt0gDc^bf|>@`0TECR(owMZOVg6uA)tNs5?R}8(r7WgSg z-m^m(<5>95m7F{eZy9q`S)lg8_d}SKg4DOlPQG%# zHJdB?)}3+DYhP{(wdCci9bZ-S$Sho${HXBXWE&zk4sQ~R46&M$jp0XKkYzqNis5W@ zda&2{4xmaX0r#-GY$U{=VSZoy&g1j_ldFd4*we66i_&Rf@KZ(HgIA&E)v{pOzf=Ct+zU&e zhU-n!=8VKl)~690<&dD@PnpmfQ(x;dniX^bCJHGA!~=x!*yNe*!{9zma89Ics=0K~ z^*(u{UkkpO`bgL12a-+HK1@-BvAVK)bisO45Ze3G9J=9T(ph4@Hq{t0Czv@(Vcd5V ztpYilHb4+5I~F2pU=Dl=am2{a3t!vPp^|T`U~UtUsCfBvxv+L7su&0^7hC`&OIiCr z14p#1LSpd|6iATBrgtR#3kFf+nVVvp60Bj0kd0X3syc8mV|{YZ!3#K;{&ozfmZ_SC z%?51!gZ)`xxInq?&H@B?wjPQ%3r5K!)(6c6q5nf$iR^_dk6->DZS@sJz*LLr3@ru8 z4J+K3zVsfxw*gMM1||&H>xG4tuvBoQoBXyyD`ztz1Kqz^%Jwxs@EBE&6(LEVL+ru- za0JgI-LQy#S?k-QE7|(>?nI^*beAvw1*eR_GLdZXlnWOk$X(MG+Aum>Bxu8w>$@N& zja zFi~K4LaK%Z1WzlJ`Or4hczdzN-N0V z;&+d$FoKFpN8p~{Lo?`g(5L&EBmu7^cQd`B>;myIt{b126;>`jX#~!`7v!tx(4d{W z!pYcCUPEj+wQu+U5EH=k8nG;~|Q3OMyTHpRuc4MYg3j6G02dhH6o zQHa0s;nJa<9T|RyLmY6oqic|?@?p_4xziH)H8pif=EjKgGb%1S`~$G zAGe8~lggJ+3>YqvH$aR9AS^x+*;ULkMk6FemDF$Z&mqI2!1^I0^O3?H#*-K(L02XO zTqZ&bJ};x5o2(){TH;kky+Fa#xY)TA6fG7{7O|%1DmaZxl~U0cu^_)7zbI~sM)tOZ zJ`SK>fgKG=9zC&d|!mov- zi~{gV31^_Qb@+50DI6s&dmN>o{V0>fS7|9wx^({BfzJx1vn3pkVI_|c##Stl z(yElDDo#2TvJ$8K?xe0(+T5MiT-T)vSs!M13grp;3F!1^zoPo;{@Vcb6nG3VX;mm}gc#g*r z!tzqV*c*xr{|xtB&WpM7U)d2M)7`EEO# zuAR3up~&CF(P*&`XQZ+BP1&K?-@}w&8ZoRYc7m{Pac>{AJfUx=qiF-1c^+q1J=Img z*{4c+a5gc9_|Q5$#r-=U&m(i`9Lc`H8nzXn^$zuwEQPYb(ZlhDLcN1KBf!bl=R!Xi zwZMnL`wKl87_+4MhLVsS7j&bKQHys70d{4TvqWr3O`e7|8c-EKumWqoNF{xnQDlL^ zhgngF(X$~@5$1=F(Fc-DE-4c>7!nCRNy?N;bR>3WqYy34cCyd}l#oKHa%7fO!>w7O zzC*f4zSocS1JgW%334gZ;HMlcYEd9<|DycueP59YV7l|yDNSlH1_N)!Pz4oyQZ&O7 z-7k#H;uXL`EW6}YiLvq~63+_NeSG$Mf6n@ypASJwn4iUu{!7uvmNK5tVjUeVZ4WH2 z-}3Dqc<&}_euJpiB?ck!q!H_GC6}~)!cJ3MXd+T>?TMk-)Q^RR)hExfe+-RCOx9aH!Y#J1JM?bnTusX{{P`9 z!hdd0Z*jJWqf{jcz2L(nfG0iAc=`mUC}CI=e*zs1wN|yFWG+l4M$&7G?zU0>@!?O* zm*g;i`yc)DURyHr{T&w-2FFOBJ$F3r*Q_TV`!QKCpF-{laz&8OTYxi`v)xBR?|PMs zUIB5nB8P+`)&?g*dMOH^>d&ymMa>%SA_Vq=2JBo3gqRKBrV;6mnJGR0_c(c!;E+&W zaiCI>LvZl~^OySy(B@^$l3wV&fuT>@{?YGJAsI}jR=U1e1_gK1Ed!(eJj+}=2fG!7Q)r{ z9q*j4qZ7U--=`xS{&aTxbo-#5uUSog1`mKkZ$x;(X;P+l7CfbAS%0x6aA6=$-=7PZ zHY%$A0zcP>#v&Gl(NtHg6VX?#Bp&G0+=No1dh8yEAVD!&6><}DquJ%dD7zcPrn=3! zmf^o02Cv#&N5TGhK@}g(+gc*TGTbClKwA}+7GZ}pba#lycTzHxzTno?+U?ivr?%k0 z_2=V)!_FWm_^C`k@yUX_vjE_(47@mU%h{93?BWlEHFM)BV#qLNYUI*(TETs4 zUqnbDC25ujmYNTLkRQrJp0dB2U&5SKOs!tk(_F(|l-mln3OtP!O=uiAa9y8fLNOoV zV;jvH1?m+ekU^X(sp3uz4At3M7x7~o7OxjTI9?6G*9B{Ni8OB?$e-}21Lz)ne+J+!d$Xo&!c z05v2>E;a=u$JaT5YST%Cvg9ts%KnQD0i5ho2AsfJ0Ed=_ZHdBYmz$6&xurt=7^ZD5 z44_>rW@~t())>TDNj0-1hbD_A zq;~O~m|~akb)w|NAKql#Awwy_iXlU_hC&TC(L>2YW&eYX>=>vGT4*Xp8$QAaChe-Y z?B)K6{p?7gJqcQwa_XNvK6WX%C7Mxr1*7#-O8m<4tWfk&xA{;TJ6s@Mgn+k^+9JYG zTs9Kx+6XUhsBP$RrKwE^dO*^+KohS120}jm)e8LbsMjEj_nbi0xjf+igFx|?zg9c+ zCFC#W;$K<;2|Y7x69F#A5{~j|TU6ZX#pqVKQA?Vo3<$K>Q$~GT3t?t$h^&uvkBvCb zEm*FF$z*VRUf2gSi6G8HPCDpz3_|H0=*Ki^k`z>_mD5&_5Cza6IapKJCZck0SfGa9?2@o|Ym*9UvKL zl!^kN3F+y#wcjBv1 zrJl&ye9bCx9m>{_)9svrDl=020kCvD&wbz&FJGTTT#HfBf6$dK%iBEE0<{qav+)b` ztZ$levn%xEqqas4zLKC|Vb^+&^maSKZ%p5=p>!D%g7B(dxo1<~M2Z3f}tqciTjj8~p-p2+MEv+WdVQOo4^Q`3x ztvrON925`~poXO)0nsurzjFD-EO|<)vj1X3;0={Yk$_s{3;?rV$!%T93z3_X!Pa+X zjZb#msN6`{(XoDvV3|=%lA^4z1sTpvymL&vb2dMKecltUDHD&)XLELd8=R&^(4`8bQddCr@r2CyrVd+}@ zZDq_8UQh)Jkp3jPW$rhsV33h-c3BDgTHLQ#T31oyjwt~DI53p~1ZrjkzFj0jOB2)4pW z*Q}=3pIL5OB9=!-d~Q9SVpvmV_vCL0RZk2L-fbRe@IODa z9$el$ZP#>MPTLEi$bda4>Tzd9pFa5)`W(5RfQ1g~aeW+D*3+D4z5**>{5nwv>f-H&=6Uhje9cmAUL@W9dpCnC0K<{i|m zAng}mXP^k!2ozM8#Fi|x>k9HfM{qH(%Xbd@;TH8ixr<5eb>#R59t3(aAJMOLU3J6H zm-LXIoV|SFN5^@ur|r!%1b;+esgHgN99S5a;5i{-nRA|r_&ElJB6$6u3VHvp3JHW- zRP@4#Jvd5K)a#MG0$MlU7@DDHK4Wt*4J5R7~z957l z-+Y1SFGr98*V^j@+#vr&`P-Yc-0JM<1I~ApoizD2ngRW`Cpz2IA1aqUjhp!LN+fws z_BAx5^y4WG_jv!CUF03=ti0QeW?EgRc<3|`*=$s`jSpK7I#jdCck!Bv@ z9jn1~EKdH)Wka+hZS;Z8r~Hslr|l#sgJ+-|oK>ip!!1^jaql9UzCK2LzHVT5D~Z5yMbb;bokI(VV1j(ND`UB zv1LZ1Cd$`CZ1&tMt?y^0!o88dbe>xM;_? z6ulv>9Gkrb-!6R=ZfR5k9`d@|c^%MAHe&se^ISg(Zg+pt!MmqvRnC3|BuZsFBxJJ& zS)Ncis-FdJJ<6a$H^bL3zyY4fl` zfk{?Zn^NF_Vg`cX%IfdyG531N5BCq}-w^%RD&7|tno>sE(2@@Rw6cj6X<$rsxzhI9 zP8v3oz(&AB$m|ZlIrBgz#v;)FM?yn~{>A(^X#ODQ$%246M>#D!^d)ciosSA}zSTSU zlD``AdQxF|wx*h&7QF;O#;b6!HpZP}#+}tNfTlV`|Aa=jrlnxfRuSkdNKTnB`m$2l z=5lD-G4*ytO_aJlG(uSd!vE*gO!B@shjb91qwD3Rf7{zA*DJ$quB#XBvdVKJ9eRDG z(5YZniXN*LIh734Z}NrPqf0^)v8tg&hwRlS%j0e}tKvc1wz%u6JQoj@y<}@jo(G5& zP8yg`I5PMsD%a^8RE?XBGe1m7{rTg}?T@8qzd?lI#x9a9&WQ&q_9RpKt_y@TVE#kJ zTNv+}xGx%63331&okRy=8NwsQU@>!-*vzhGB2)C?T_mi$SO%zgH8OZ;cxYCr*_5iY z=`S;07)W}*x+i*8d2GN2MJqB;u1nw2C%uxP1B~SB^*SxyYv)S`8P(mqPgRYYsyAr_ zL`T5{{G%7%yx3DiElGU_j@xNMLjS+$bb}N7)o(0D_>&7XSr9m`oADh%IX{Oo&}}84 zSj$uogN!eO3@|AFaEQ0I)9(ipKnfRNdc^cplLdW0^joB|;c(gz@dabpzy8I8uhso$ z%4vB@*+c8jLd}`lKfzGtH5l4Yk%1sO^&jv1#{zx!H0cWj_`+qK(P8Tsp!wwRV=YW z2kqY&_du|=Z2Z4SIX}1N>r(0@^D!E}p!!8T!`u!z327IM@eyvskmniTuxx5kwbi8D zyuQ$Jeaw-P^~*zYbt9}H=)u77L3{m(`0M>&mO?t`j|8^>diR$XYOQ=<<<=JNU+Btg zl@@Oru&~pUlFn$%7Jb$KVDTB2c1#ZUu;jgT;S$JIX%N{>HYqVre0de_JO>MewLZ`t zjYauo<~A(Sp#$VIZ{7|GHTmu5d8m+h!rTkQne#wx#kg(8mPwW2>O)a66xFv|-=nbb$mT1?W) zEs^#$ppyj?C%>Lab<-hV_g3GO@@5xu2hgN#V?L@Q+eU}<2OAB{mnPMQchZD0Z!&CD zPS(k&z4ug@tx_Zz(Ue$?jO!guDsNy&p21~ z8O~oS@Dou`)Uj{C%&zrt>Y~xm>fuRA%l?xT#WV7wVz6lBeM{)sKEc=}WCX9}@qaOg z{am8-zCW|(!m4!~zADwG#GK{J_oY(w=Q=g@BzY^y_DVAWW!^NkROCJGtuFGTzUKnM z2=I1*O?99D%t0Es*VnNc{5c`(5xSD;n3Y&13m|7ytzWr@PpWSOfYl_;t>^Zh_@vs7 z^g0IQhu1L>D&GC?F}&I1;n|T8*@@tGmdA@9{9viz1RreQVL8X|jZc4vgjekIl@4=X zH*Xd0kvOnpEJU>DW0)ve@g@GIg9NYw%AfE$`Bv8dON3^_>2$q8rDBapE`ymmy}H65 z{BMw#^r{=yL?eehhdi?siY7O8EX(+36DZ!lngY`HFXrN((MnXxo!7h_Q8<#sW}Xnt zBw&9;tPLE%=JN1AXh~YF6h^^FE$(&k;@soj>%M;~w^=O&$ov#|V76S{@1Sejjx$Jc zHEs#*+ER81(1Z&BKq)1^;kTNv;EdCng$Ywsg!^eRhYs(?{g<3!Udg#TH_{MN^!!`e z%7)qyfXNQC-%7(qDL{)O9VtR7!6S{wqjg;<_`;qth^$?o_Lg09RXTP<=ssg*Ss%(V z7|Jo!Go9j*5Fa_Ea(exCZwV^QIWE)2Wtr*eX`v|!jz1ow~SlG z=4sJV|84&JTe@3b_!pW#V1g}(!u|8AaG#O?qWtZ1VEK?~*OnVcSl%>B+XaiIBQ*kH zaeZ9*)SGzuap??Ub-)(~Ev@mJM1n`$M_uA)X5iKSj^dhw(UoQC=6R^vUHmiF$*?<6 zEZ?;v3Qv`-i-1Fqp8#aHGun4BI<&C$I{5{Ypx)>ZzYOzrQyW6y9%TO-?RB| zrPzY+9bH$zio*|)MW3&aSxx1}u|kS)`G%$W2e}0eVR82r#6!Djsv&!2Y6lJAHzY>6lx|v_DN`*yy0D9xE>DGldqQk4MmHn>o$ea zCK>sJ3zdlwfb-yi3LUqS3q@b;|LPVn0l^$F0U2-s<2=&881lrWh9AhtN$2_+I-nAi z*b7*Yt)$kgRO+=&X;J`G4yEBV(W3BBpJ4(@KR&~NnD0i0{J=X#syiT_rWzn+z;bp5 zLtJSRprwk;m`&T%SVFg20G20_>WuD;7yg;%;*}K*|4l6ZCo2X=!KpN7NB3))R{nK}uoTzkUn6k%fmyRyMNxfkBF9iWA}SV5GpgRlw5`?6i)bE^RVvNVfz~ZuHWh|Sq60;2j?)sG0Qf>}4?!|Rks;u_X znFezLB3-!tXG^cf<@=4U(hkh8-Y16?6pCT{%(w=^5BK#nR6DJ+EZR0V*eQ)mDHpn{ zYim5cM3V-o4HG?fPp?G|)(t1Y&OH5~r>~8zg_dm_2Vk4ftMVEA{q}iWE;vPS_3mfwa>wOyBb{=)|HbXJx!{5B zTV_F?f|rT!58>fHEex)}#txSpoaN0k$9?h2)fUXy2f?qgOLupb9)B!;%zVEjY&hCb z7G#|mm-ZiM^g80H@i<958((ZB5$;^@XuIty7xwcKIbtRxHMK1z#Xcnm`nvt;`>A{F zoFT?Nyx>iaabeJmh#@3E`=gSaer)uB=}pz1yXjMU8Q?|*Tm}gKKDYGkjsz=lI&a|A zg7ap$Yi`>?+R$1pDQ|UVUEZhV#0PM)=aVYQaLW zPntr-fQDZvV31O=kIc#R#3{?u$F){UcgzN*mJg(DOZn69SEUCV3xxrHn1ho^1o-U} zotJoz0Bu*gbcle8^>zdMBx{efC!P*}w>hB9$c-Vd?1=8_sQY8RdrCz9D%*s}IfYj0 z@$gbKAokC>riUy~`{AAF*id*+%HDZs(%!DV+U2xq5UzX(z=37&|KsZ~ zgW~F%uu(WfAUHvTOK^t-x8Sb9J-EBOySqbhC%6t0++AmY;5xY5e8ZjRt@=)#de5&_ zHE=b(dUf~J-HW|P4LsrKdOFcA4klXS$?QLsnG%=l0N81J755Kwmx`@|uP--h4 zb0CIyw?$PAAF(4ARw;QpKff8Lt%u%jYQ_>upf^e5(86YSAhX#CVQFfhTBEamE)zWo z2Vt}}hd7*eocheTO)&k~vObk*=J+?~Rk^m(==meU2iY;=0`#GazA3yU`lY)___ z!#YX8q&dU)J1RC&!`4Kg4)36A-73=j#K$bD@DC^UWP}0Px%G>~|6N9+0(EM?rCt%+ z+l_nEb3(BAs%)z4~$xkh}sLzR>k}>w|C#^g0~gs>yZz$X0q*ur__^ zg3QYxE>Bgv(NH7+F0^vq5V|$V*)RUigxSaxJ6#`A6;T&`=Xw8Ys!=|P~{H+aksDjIAx#r~l67`hG{CSHh zR_^LNxTVJ2($D71Bja$(A^(IWh$C*L#@a-`ilHb@YFWu;?fsZoCiCjxxMH}x%S1Gg zYjeYyCv}KxyM4iiE=zo3)nopqxwL5`vGJhXTGbV8p0Zq4IkS{q(K>%+pq#oKTwczQ zVZb$)Me2T(Ev6)KJwa3B58G0wDP&CZL#ZRb^Dgt$SYYQ zrvlxYsmdDrz~MlQX6UrQMjo_g25;{v?dXZ?eI_E#j~e_?I4HGu8cR$f$J(F!9OtRZut(IyY~ovaxLl zY60x*bXoS+mhq<>y#0{aKx$agglF+b>f>KwlguT$+~{U)yxkA;lq0x~SBjvV7QR?65zX04Ritn=L{ob_ew3S2D)bxkzSyY@`$)NiMCpUQIp`nr=fbo2?o; z=FS>LOCu2uxjR$B5OVzmoXuM335qHzK*y*XrZj>^C7LbfhbyL$EDp+?Fg#RZbU2~{MnpbR0^+N+ng@GH_&W3_Swj?W|4=NZ+l_*#4X*JzO-$H?3cR( z=`-}ZEd@I7Q*x(Wsn)$9OAt;`Bk!J7`*JYZQ2#I4sR_4;JclEt;j)t_91D&?_Ait( z?AqR3Q%1wa0~Cu{mVPqg!!8UnX}({|VxUpmwwJL?*yk9&hdxP>Bh8!YRt-J5y|(f_ zvI?0fIs1i zhP&h1Y*f}o|4RkqgY)+3X&m;Bh9|WBQRnpJ$&l#f#q+czb!Qofc$utqc(TCTU4tCD znBr;O76{z8C*004I>lpbK6j9>bA2s1pt)T^?A4W~(aCO8C~uP_%P9vn%Rn!2_17VQ ziTEF`i1VbOpBw7is70h#9z`^ht++>3K>A-@{_%r#1L*RVC#?NIy_rd#`tt-1r=gm- zqb&XFo%cs)yk&aawQhcXD*TpO`m-?FnZly}umny(Usn;+5k+ zhJ&W^S35KW4FQUV`OZ{uPaQdO^A5xPtjI^O44ivlLJ^AdchI6;+iHtP5U_%clma*< zguO8wQ2zy^tMpC|#eZ?7chZW#=ITh)>S_gf+8bVD5+Gc7xjjg}*WF%&YL-&XaI2ho zZpG7u!gWg|F#*_c$o#)>E$uB5CDu|Rk1Q3qoJzz31Htr*BSZ4iqk^{i9i_V@ICl<}tLsfym#3aw&9riWo7mxmz&ilZ~BVn&(t0@FpyU2Hl<`|L` zW|qPt3}BV9?!*TYOJzPD;wf8T7>ze2^?@Pmu7e|3T&yWQ5)A*i1=+>Z%vb=~-V^`t z4Sf`p^V|3`OjmWEewuRdNv(T}GUarw$#y|C0sT)Cuz)mh%!Ck>V+6v7dZ&#%>&YwI zLkU(v?3JXZ(Kl~Wc5gH>V3w6yD1*UDU$A68NV8dN&xBaWsub-PFx1i_j-=T9h*qv= zS4n)o69GlLii3zWm*s>(Ym_Yj{P7l!#WsMz3pfA$kbJssD(6aZR=$ z^Q_yYJ#4WDEcpj|F!-l88*!)zjp--S@`X)0gN<&nr21`DyF< zRQL3e>OY!wjBMo_KSE1ppk<5(tBVhbs=Z^nj8B??mbxsg8!l@-@$tQ-D> zEho@w{G?8@l$$nGnwF5Mex+t;ne)r47^?RdP!92dSj~ecz7i`+Rp( zu@OUIbNaOvV0l_(&mFq%(t>hy)0yn`KZof2e>=nsC}(2+=U9eCOcLMcS<3Eya%9C4 zeVsCFte*`EUJ=tpnrJ^Pm-Hj^FEv8`l?Mw`V73&2JLdiabM0TVJkMv+MZFX%ncE1A zG;Jc+Vpf$L`!GYbE<=@_HnX1NX4*WG1MbKOV2VSA(;NBzAJ%~)N9)g?0>QV|{MXy( zi<3M-c*=K*r~B^husJCOC5cOR8GkIPjE|TJx;i;7kp%FEYO`;)z*DG(rki=q^R`qZ zH*2zPJH3x;0L4F`6>eS(pT+yDY>1RsyVeVki`M-1w-w~;O_gD$hpX#K;6w%ZI_BiL zX2s^*VQdJzAn!8AB9rt>bvoI2-~C+LdAES-);*T^_VD!a_ViQ$xwqi* zTef@Pml5ToGz=A_6?_TsB0ERjLW+_^krfS(?OT%q*)$u%z0$sJ_9lA|5IZ`m|4dQc zG-$p9Y)**&#)l66O(-;*StY&qBf}SEkFX+0`m{`4XAjM014YAP$vQ*T1_l$9B3PuV zh+>MF*G=n&<=kx<*|giWOGXA$pOWOw3d+B=sEa_Mn9D8Ub)OoB#NwlKbu~Jz2(ps0 zw{%agUHOSD+-IhvtQSdV>@%FK7I`gfmlHM@cBVgPNpr_|pHfH+UeV+IIPoowMbYb& z`~79cKE>%hz|ZLlxH8KvAwDd_sco}WRA5Ajc|bj*Sh$rJB_SRkQ$QiY&1ftBlO6gx z-(?Obmvq|Hyzp#uGXsY7u`<~}Tm+So{gt34yS%B8gD9~A5vE8d%mX*mL}+aW6>~mI zr#FEh{t~CwB&f)58K`Izs~{Bg zM~k;+TQ=F_^b9h{>VbA`AH3h&^&9@IsDiuFrHYZU9-v1gc*S(o_f#uZ*_j%?3W0tB zxwl5AxP5e@c0u!)oG0+ZuBIqhl{w|BL%t=!(Xq5$^v!uV_k-i@2I})Vaaa8goqcq@ zc0tDPoeLH1f*ohO=!90NY6Ijpe+a$}3J}1GvFZ9pQAc;k@KB)1Yu10XS@v>V65N*?Is}*?+u^ckV>%WNF@M3I< zEOKI-1KuyT+#ZdZ`VtWn`rN+Q`<(5rZ>%v^+t*osi)7VJKX9_I^Ej!9B zk8|8Aq`tGyv43wo62^gB=BZqce@iCcIS?|bQo+uG!Zw)Jt{vS}IE&%6b8oUPr`pruRF!w!Wbj^SQk} zpiMlg_JI$#A&M<1)ruEvD9|2zk^25WzsFqUr2g{iF3=u3TG}yM<=~L7p);0E*+dNk z&T<$pl9IbLOIaj}cFrmwLJBw6f^-Tdg7RO~tSxIVex!eug95nt&^l1-75JaUj)u)o zzYF3s${zi_3{t=+(&BA z`A@NV>H|Dcwg?N%d8lILipo&M6r-hoL{|r47W5~yD#+2As*$=Sh6@`19h%m(=;Bse z(imfDP8XM4;V_BeOfwFHLaEE`zo--xT0(_D-K-FAFhfvz>)ZTLwgEY1Z(f!2L<|FB zHZ*5QG4!zU`#v_gUIFEabvt<;#JxSwpof%RZC~pY4SqiQi$|feW!D<*8lCW8NJ9NS zkoEOMVp7l+TRN;uVHz#XKp{UHDDGDnQ5IOxO4Pmn7_`vJV3LZfO_^eRQ&-~)NoXWI zOZ?|zi&JbTdnk0H)9c8Iu~I}1QKQJ&K0Yg-Tzpod#W(h!f5W&{5;)vGu_UN`WzQOJeGGRQ5Mg$JGsse{pUX(H?9Y7 zrSs=VUwOdugw}B~xM!nTU}2|YuE=F4^C`^L(d{%gHkY4wd&7p=LXCf~EXzWjv+e@i z1jAjCHtqBn)vugAuk5W#`2nfwjXVea5B{e_jdV0-ZjsEd9SD`eE&GO&vK-nrvw)GY z6B1p~jtDobbJ|UnzKSRn#f}jbKm-B|R%of^c-9v}LkCIb;qid!D zLRY&C;ndqze!R)4gaK_P85O z;f9Q!gtyGfSSHq03+8cwf&_lAD9imfZ9Ep7Tt0*o6n;N$LIR3?4vT)fc6qyrLrkS% zLxenF?RoduKrvLSe=?_wVD@Sze`345xZNJ!9Z0Sxh3WxbZWqnVifyY`91jst{#t*S z!bEO7m#xSE>J!zCPo4BaFNf4qrBAW~ZP?EZ;X3o#p4q&DJ1upZO@0A93B7^~J#e9A zf2WWVAgl&WkF?W3LCh=oE&^Ki)1~avecLwkR#l}y>UXy+Erku%O+=bT*&W zC9!SXvS@P^!P&g;C+ie?MX_CB#d-qNJa;An7p?0Q7*S>GR5uQV5*d{@XU;+*Rrq{= zDlMR|fB%WU-0mXfws))*O{8DV8IEh)y7U>bpO;G^BYj#!M1S0x@{&yhNXf9K0fgnL zYNT+K9Gl&#m9n;RYsh>MCS~})U&svFW!X7^fZU@be43lmQJ*u=P7UFq?P;Z3Zv2HQ zjYSi8(r4eQRSE-hj6N1lZ58k-;g_CBKaCSsn`29o7=j09n}IeKC#TM%|ckWaq4 zm#%2S-YcF=*H}Reny8YY?xm8ltAb=lKhG*mJ>elb)~VG^_#;LEG08~sixwFMS2ktj zwkDb9Z-NzKo2iP=|1uj0yQU5VeTy`02}Ju)h1KhN=6M-%vIo%>@OT0CBBqwOB@4Rp z+|ptQ`R`uQg5Ne+)sbq1Bjwp-FbQMkBPQ>_UJy;K{F3@v$-#-($-;H_SB6RuQ ztWN+7TyO4kH&u$=v3#?~b0#{Zw#19s&S=-AeUhQmh7%R&WdGkT{%48Gh)tDh0=T*G zfcyfM<;HuP=mm@bsc7V$_8UhqavvU@#^5Kc5G7Iv!6Lpi&a{Pye+EPbj4($)Zl3!A zxs63CZOI$4Yv~HHl9Fmvn3=+w1XGtj+zmBF1O42VKL>es=QSpTZ<$-cUJX5-W=D$gSe~1k1IzP{H zPSSvnWNkzlT!f$k!tt9h9BsfxZ;UOemRHQ*HMs=TYSuVeQjI$p8A8=A>Oxx zTg3cN7bX!pTJ1-Nsy5)c*U+-RMklp&>xQG>3wv;qGi=Z# z^eWNNsVisLgi^Q*d4@a>uvmz97CeAEg+9fZbNo-#NBsnN6|IX)U%( z#PY;hRF^qQM_|`bb0_njq)o@6umW+aE}u}(NnKw~x2x?%V)KZo7L|1?IaGA-@In#? z6!ygVh5No=4ej6A=3OeHqo~S_+u+jc$=-dPX`8zq3j7lXtVZWd2$9|XL1O$(g2*x#k`7-WO>?}t%v>??# zB6U4)@uXmwO$!{`hF5`=|IqyP9_C%%eUGHqo3`y9_sU1D@B2$O9ZOT69zt^up9N03 z+%BIdDs1_Yn!AxpQ;&S>x#kg7Xh|v=2^;K~1@&3NtP|K+DnTwVCZ;krvpPGU@tI9k$n5AvSB?0Q zS>O%O`^Z7RC6^`%RZ|MOCRx3FX5j69AaW2jcs~5Cy`OTt{)H~kd?35%PbJ{&>*L_I z#KXOYdryfoIlC}qWTN0!I5$Lixo4Z}+qF*ELGa99cK6cX7 z>)Y&mr+2X>pyxgB+3yt$-RauvMN74}!SMkN=D>q_LR^HnbJn95&2Ek>5VJ*3!^ws zt4?%@Xio0S^B(hx%jyZcb;k;yOo4y^FmKlo!#npB25-=DD82dAhl>Tm4{7BU>1A36 zWRaQL2nx$Me=AltE{Ke`%xWBP>IfmFE8dfb==3B zt+j72nfPVtbL0xVaZ;O+YqxkYueowvJ07q@vjGgn(^Ek+qVBdt3dSccG6#`uq>-?p zPw`(hg+wN1L}Eq;OjVWzmDmlVKQQCIrzBKpt*qfaLFq;Sa8l{cVs8kY8(E* zN=_y&5)+oCMd5%{V~2V$N#zh?=kaLW1tfG+pE|y6p76OlZ=B`JpQPN;f~x{y+g!SE zgp{$zoH()Xp4Jnsuiq;>nA&o<_*&x_K^_CyufX8s0N z>zSac*w7Vm8L>J8 zEZiFwcRV6oQ1^-R4dkpGcUG@&3*@A?SKs{I_cOc~J(NvV)Lva}Vh-QZijVq}#kXQH z5jATg*hSb+h}8-v7nspPhcj1)`&OyXe$v+U8y<=29{v9Toq+_{)xUbVzjEBh@ON@Q z7_5O^>!+*cfJcOlda>MVYut3+_OrROo6gP0JM0*%$evm?y@G3Ww=4UH(=4Rk;L_-N zBN$%J!H1M(3Nw~nxL4S^Nki^)|oyA*LlbxQL?8NS`%+A>p_H|X!Y zC-Khw^dOd2LDAM@@6>6@%Z72NWl6KZX^#b$T+JTClVYG%c5sx=&3P4^HDSos;w`p% z9=pd_J)23@c0~ca=5J5$iuDQmV?gHFNa$^iN5T7bIm3cjn>zcrNsk=>WWG)P@wV;- z9r*rbyhPU#vaMsGcQU@TmwjwY*jQ%3BT({n8PsJeHkviPvk>YqXPN8GNhv7M`Eqz> zWZ89m8?$EHpUBR1%$W83Ab8oC--HQUnbGHSl1vwUb{X-ky@5Nsz( zW_Lazwk>iQZ#;KCYPl^Y0M&!Z-ilUctKqE}?;h{Nz@|PAviWMY->)sXTOpq>*k%)a z%d;^p;W?<1yu}yk;yxmAZ293e?Rk6Zd;Zhu1*qrC-(t7*$(6e|dz0L?9K`FNRdO=d z=KOK{$(;U6Ldz_&OUc*vz?L8OC7W{n*%3TguG~=1DN#e&b}D-?`b8U%;OK{LI3E{B zU6fVo;)#%&7J#ryC+9DSMIZmRi5*Eo3RL!r#^0BFMwqqn6?0wL{hhEjH-|#qFuY2m&@Dw%gQ)c)80L;R= zwRx)NH~~&KQ+@DbTr7AvR@HpHTP{!7h^}r8y2f*%Z!7l=JAGLWeK(7ISA*iBdmQC` z@1h2T$3^;V8lgA`i@INF|CrHB+=V5$mtj3k)bOX!(Bk>l4RQv-uew@BA1?8vLRJu$ zo0_75sK>q>RrSs$=%E5!K(-hwTd_=0L@&oB;H-hmqSPAwGcbrtN3o zCVeg2t$kOJrJj{-VbSROvd0zz0bcHhoxhomYLCE!K8J>FAv#uKKJWXp)OQ|Nnx-o2 zClDG{d!LGZsv=OXz?!;k;Fk062*dmCK3bbPm8^NfKH3Ns%nE8%#map3ekk#&bd;;~ zX$zghC~{CDZ3kX|_AWL+Ca+=(u1s)U0&kj<4MHn7X`K|G0;eRbbOWq@+O=i_ja(8Roij}fGH9ZigLv?{=L0&a$tF!dk1o$aD(CnStw@@|)fty^u1YAi>d z)W-TGVp;il2$?zV5klbY`ULj9Pd^ETL+!+kNymA|HToTeNxvhS4s=Jz?e9q;EbeU_?DO#Zg929YDDNzHT|;* zt6VY~mQkj}Xqy;IoB_$H)o*`gOEVIjS`ll!1`JQYmQSV!kxgS0E@A^;GzWx@$uj+2jhn_q7}xyvjRhckL_y# zge}=cRW7O=S(*YZfEe;Mp#_kIMuvs?mByP&)4*X(YBPfOTb%0nUUpeSRI*&#Y55FD z?143v48paTc6PSd^JGx;C~P_Qpk=9MQ&DUun~WI zVeRDQM4eaD^L*Q`2Ipd-0=3;x1Ke&&)l{*!mTWkt%P(;K0ky3yy2S6)!5Uo59&$p& z@Hj;!?s>ZcFI$x9u(rBxrev8Fe(P6dcF?YLhdejQA6FfPB&?|XMMUh~*aH>DQoI$5?* zuEZh*RL3wF))dxHv~2G;UP$3}46#_Dw`yz5xH-s$-VOh)*mY4EsSd12c(3@{-Kj_h zP}{3)miMVZySoZ>H8xEl?fDDsWC�v;L$hnqumq#%Q&~bCD~dtqmHn?q_jJa+^^T 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%0AdcUA0@M3 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

b7 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

6HtE@>Q|5mvQH37=0N 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 RO?c=MA;jMto;NH2{{i5^BW3^q literal 0 HcmV?d00001 diff --git a/x-pack/test/siem_cypress/es_archives/timeline_signals/mappings.json b/x-pack/test/siem_cypress/es_archives/timeline_signals/mappings.json new file mode 100644 index 0000000000000..a1a9e7bfeae7f --- /dev/null +++ b/x-pack/test/siem_cypress/es_archives/timeline_signals/mappings.json @@ -0,0 +1,9063 @@ +{ + "type": "index", + "value": { + "aliases": { + ".kibana": { + } + }, + "index": ".kibana_1", + "mappings": { + "_meta": { + "migrationMappingPropertyHashes": { + "action": "c0c235fba02ebd2a2412bcda79009b58", + "action_task_params": "a9d49f184ee89641044be0ca2950fa3a", + "alert": "e588043a01d3d43477e7cad7efa0f5d8", + "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd", + "apm-services-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", + "lens-ui-telemetry": "509bfa5978586998e05f9e303c07a327", + "map": "23d7aa4a720d4938ccde3983f87bd58d", + "maps-telemetry": "268da3a48066123fc5baf35abaa55014", + "metrics-explorer-view": "53c5365793677328df0ccb6138bf3cdd", + "migrationVersion": "4a1746014a75ade3a714e1db5763276f", + "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9", + "namespace": "2f4316de49999235636386fe51dc06c1", + "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9", + "references": "7997cf5a56cc02bdc9c93361bde732b0", + "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4", + "search": "181661168bbadd1eff5902361e2a0d5c", + "server": "ec97f1c5da1a19609a60874e5af1100c", + "siem-detection-engine-rule-status": "0367e4d775814b56a4bee29384f9aafe", + "siem-ui-timeline": "ac8020190f5950dd3250b6499144e7fb", + "siem-ui-timeline-note": "8874706eedc49059d4cf0f5094559084", + "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29", + "space": "c5ca8acafa0beaa4d08d014a97b6bc6b", + "telemetry": "358ffaa88ba34a97d55af0933a117de4", + "timelion-sheet": "9a2a2748877c7a7b582fef201ab1d4cf", + "tsvb-validation-telemetry": "3a37ef6c8700ae6fc97d5c7da00e9215", + "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" + }, + "name": { + "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" + }, + "actionTypeId": { + "type": "keyword" + }, + "group": { + "type": "keyword" + }, + "params": { + "enabled": false, + "type": "object" + } + }, + "type": "nested" + }, + "alertTypeId": { + "type": "keyword" + }, + "apiKey": { + "type": "binary" + }, + "apiKeyOwner": { + "type": "keyword" + }, + "consumer": { + "type": "keyword" + }, + "createdAt": { + "type": "date" + }, + "createdBy": { + "type": "keyword" + }, + "enabled": { + "type": "boolean" + }, + "muteAll": { + "type": "boolean" + }, + "mutedInstanceIds": { + "type": "keyword" + }, + "name": { + "type": "text" + }, + "params": { + "enabled": false, + "type": "object" + }, + "schedule": { + "properties": { + "interval": { + "type": "keyword" + } + } + }, + "scheduledTaskId": { + "type": "keyword" + }, + "tags": { + "type": "keyword" + }, + "throttle": { + "type": "keyword" + }, + "updatedBy": { + "type": "keyword" + } + } + }, + "apm-indices": { + "properties": { + "apm_oss": { + "properties": { + "errorIndices": { + "type": "keyword" + }, + "metricsIndices": { + "type": "keyword" + }, + "onboardingIndices": { + "type": "keyword" + }, + "sourcemapIndices": { + "type": "keyword" + }, + "spanIndices": { + "type": "keyword" + }, + "transactionIndices": { + "type": "keyword" + } + } + } + } + }, + "apm-services-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": { + "buildNum": { + "type": "keyword" + } + } + }, + "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" + } + } + }, + "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" + } + } + }, + "lens-ui-telemetry": { + "properties": { + "count": { + "type": "integer" + }, + "date": { + "type": "date" + }, + "name": { + "type": "keyword" + }, + "type": { + "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" + } + } + } + } + }, + "indexPatternsWithGeoFieldCount": { + "type": "long" + }, + "mapsTotalCount": { + "type": "long" + }, + "settings": { + "properties": { + "showMapVisualizationTypes": { + "type": "boolean" + } + } + }, + "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": { + "dashboard": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "index-pattern": { + "fields": { + "keyword": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + }, + "search": { + "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-detection-engine-rule-status": { + "properties": { + "alertId": { + "type": "keyword" + }, + "lastFailureAt": { + "type": "date" + }, + "lastFailureMessage": { + "type": "text" + }, + "lastSuccessAt": { + "type": "date" + }, + "lastSuccessMessage": { + "type": "text" + }, + "status": { + "type": "keyword" + }, + "statusDate": { + "type": "date" + } + } + }, + "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" + }, + "eventType": { + "type": "keyword" + }, + "favorite": { + "properties": { + "favoriteDate": { + "type": "date" + }, + "fullName": { + "type": "text" + }, + "keySearch": { + "type": "text" + }, + "userName": { + "type": "text" + } + } + }, + "filters": { + "properties": { + "exists": { + "type": "text" + }, + "match_all": { + "type": "text" + }, + "meta": { + "properties": { + "alias": { + "type": "text" + }, + "controlledBy": { + "type": "text" + }, + "disabled": { + "type": "boolean" + }, + "field": { + "type": "text" + }, + "formattedValue": { + "type": "text" + }, + "index": { + "type": "keyword" + }, + "key": { + "type": "keyword" + }, + "negate": { + "type": "boolean" + }, + "params": { + "type": "text" + }, + "type": { + "type": "keyword" + }, + "value": { + "type": "text" + } + } + }, + "missing": { + "type": "text" + }, + "query": { + "type": "text" + }, + "range": { + "type": "text" + }, + "script": { + "type": "text" + } + } + }, + "kqlMode": { + "type": "keyword" + }, + "kqlQuery": { + "properties": { + "filterQuery": { + "properties": { + "kuery": { + "properties": { + "expression": { + "type": "text" + }, + "kind": { + "type": "keyword" + } + } + }, + "serializedQuery": { + "type": "text" + } + } + } + } + }, + "savedQueryId": { + "type": "keyword" + }, + "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" + } + } + }, + "telemetry": { + "properties": { + "enabled": { + "type": "boolean" + }, + "lastReported": { + "type": "date" + }, + "lastVersionChecked": { + "ignore_above": 256, + "type": "keyword" + }, + "sendUsageFrom": { + "ignore_above": 256, + "type": "keyword" + }, + "userHasSeenNotice": { + "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" + } + } + }, + "tsvb-validation-telemetry": { + "properties": { + "failedRequests": { + "type": "long" + } + } + }, + "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": "1", + "number_of_shards": "1" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + ".siem-signals-default": { + "is_write_index": true + } + }, + "index": ".siem-signals-default-000001", + "mappings": { + "dynamic": "false", + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "client": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "container": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "doc_values": false, + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "integer" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "doc_values": false, + "ignore_above": 1024, + "index": false, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "observer": { + "properties": { + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "signal": { + "properties": { + "ancestors": { + "properties": { + "depth": { + "type": "long" + }, + "id": { + "type": "keyword" + }, + "rule": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, + "original_event": { + "properties": { + "action": { + "type": "keyword" + }, + "category": { + "type": "keyword" + }, + "code": { + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "kind": { + "type": "keyword" + }, + "module": { + "type": "keyword" + }, + "original": { + "doc_values": false, + "index": false, + "type": "keyword" + }, + "outcome": { + "type": "keyword" + }, + "provider": { + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, + "original_time": { + "type": "date" + }, + "parent": { + "properties": { + "depth": { + "type": "long" + }, + "id": { + "type": "keyword" + }, + "index": { + "type": "keyword" + }, + "rule": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "description": { + "type": "keyword" + }, + "enabled": { + "type": "keyword" + }, + "false_positives": { + "type": "keyword" + }, + "filters": { + "type": "object" + }, + "from": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "immutable": { + "type": "keyword" + }, + "index": { + "type": "keyword" + }, + "interval": { + "type": "keyword" + }, + "language": { + "type": "keyword" + }, + "max_signals": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "output_index": { + "type": "keyword" + }, + "query": { + "type": "keyword" + }, + "references": { + "type": "keyword" + }, + "risk_score": { + "type": "keyword" + }, + "rule_id": { + "type": "keyword" + }, + "saved_id": { + "type": "keyword" + }, + "severity": { + "type": "keyword" + }, + "size": { + "type": "keyword" + }, + "tags": { + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "reference": { + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "reference": { + "type": "keyword" + } + } + } + } + }, + "timeline_id": { + "type": "keyword" + }, + "timeline_title": { + "type": "keyword" + }, + "to": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "updated_by": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "status": { + "type": "keyword" + } + } + }, + "source": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "lifecycle": { + "name": ".siem-signals-default", + "rollover_alias": ".siem-signals-default" + }, + "number_of_replicas": "1", + "number_of_shards": "1" + } + } + } +} + +{ + "type": "index", + "value": { + "aliases": { + "auditbeat-7.6.2": { + "is_write_index": true + } + }, + "index": "auditbeat-7.6.2-2020.03.20-000001", + "mappings": { + "_meta": { + "beat": "auditbeat", + "version": "7.6.2" + }, + "date_detection": false, + "dynamic_templates": [ + { + "labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "labels.*" + } + }, + { + "container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "container.labels.*" + } + }, + { + "dns.answers": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "dns.answers.*" + } + }, + { + "log.syslog": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "log.syslog.*" + } + }, + { + "fields": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "fields.*" + } + }, + { + "docker.container.labels": { + "mapping": { + "type": "keyword" + }, + "match_mapping_type": "string", + "path_match": "docker.container.labels.*" + } + }, + { + "kubernetes.labels.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.labels.*" + } + }, + { + "kubernetes.annotations.*": { + "mapping": { + "type": "keyword" + }, + "path_match": "kubernetes.annotations.*" + } + }, + { + "strings_as_keyword": { + "mapping": { + "ignore_above": 1024, + "type": "keyword" + }, + "match_mapping_type": "string" + } + } + ], + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "auditd": { + "properties": { + "data": { + "properties": { + "a0": { + "ignore_above": 1024, + "type": "keyword" + }, + "a1": { + "ignore_above": 1024, + "type": "keyword" + }, + "a2": { + "ignore_above": 1024, + "type": "keyword" + }, + "a3": { + "ignore_above": 1024, + "type": "keyword" + }, + "a[0-3]": { + "ignore_above": 1024, + "type": "keyword" + }, + "acct": { + "ignore_above": 1024, + "type": "keyword" + }, + "acl": { + "ignore_above": 1024, + "type": "keyword" + }, + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "added": { + "ignore_above": 1024, + "type": "keyword" + }, + "addr": { + "ignore_above": 1024, + "type": "keyword" + }, + "apparmor": { + "ignore_above": 1024, + "type": "keyword" + }, + "arch": { + "ignore_above": 1024, + "type": "keyword" + }, + "argc": { + "ignore_above": 1024, + "type": "keyword" + }, + "audit_backlog_limit": { + "ignore_above": 1024, + "type": "keyword" + }, + "audit_backlog_wait_time": { + "ignore_above": 1024, + "type": "keyword" + }, + "audit_enabled": { + "ignore_above": 1024, + "type": "keyword" + }, + "audit_failure": { + "ignore_above": 1024, + "type": "keyword" + }, + "banners": { + "ignore_above": 1024, + "type": "keyword" + }, + "bool": { + "ignore_above": 1024, + "type": "keyword" + }, + "bus": { + "ignore_above": 1024, + "type": "keyword" + }, + "cap_fe": { + "ignore_above": 1024, + "type": "keyword" + }, + "cap_fi": { + "ignore_above": 1024, + "type": "keyword" + }, + "cap_fp": { + "ignore_above": 1024, + "type": "keyword" + }, + "cap_fver": { + "ignore_above": 1024, + "type": "keyword" + }, + "cap_pe": { + "ignore_above": 1024, + "type": "keyword" + }, + "cap_pi": { + "ignore_above": 1024, + "type": "keyword" + }, + "cap_pp": { + "ignore_above": 1024, + "type": "keyword" + }, + "capability": { + "ignore_above": 1024, + "type": "keyword" + }, + "cgroup": { + "ignore_above": 1024, + "type": "keyword" + }, + "changed": { + "ignore_above": 1024, + "type": "keyword" + }, + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "cmd": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "compat": { + "ignore_above": 1024, + "type": "keyword" + }, + "daddr": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "default-context": { + "ignore_above": 1024, + "type": "keyword" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "dir": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "dmac": { + "ignore_above": 1024, + "type": "keyword" + }, + "dport": { + "ignore_above": 1024, + "type": "keyword" + }, + "enforcing": { + "ignore_above": 1024, + "type": "keyword" + }, + "entries": { + "ignore_above": 1024, + "type": "keyword" + }, + "exit": { + "ignore_above": 1024, + "type": "keyword" + }, + "fam": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "fd": { + "ignore_above": 1024, + "type": "keyword" + }, + "fe": { + "ignore_above": 1024, + "type": "keyword" + }, + "feature": { + "ignore_above": 1024, + "type": "keyword" + }, + "fi": { + "ignore_above": 1024, + "type": "keyword" + }, + "file": { + "ignore_above": 1024, + "type": "keyword" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "format": { + "ignore_above": 1024, + "type": "keyword" + }, + "fp": { + "ignore_above": 1024, + "type": "keyword" + }, + "fver": { + "ignore_above": 1024, + "type": "keyword" + }, + "grantors": { + "ignore_above": 1024, + "type": "keyword" + }, + "grp": { + "ignore_above": 1024, + "type": "keyword" + }, + "hook": { + "ignore_above": 1024, + "type": "keyword" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "icmp_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "igid": { + "ignore_above": 1024, + "type": "keyword" + }, + "img-ctx": { + "ignore_above": 1024, + "type": "keyword" + }, + "inif": { + "ignore_above": 1024, + "type": "keyword" + }, + "ino": { + "ignore_above": 1024, + "type": "keyword" + }, + "inode_gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "inode_uid": { + "ignore_above": 1024, + "type": "keyword" + }, + "invalid_context": { + "ignore_above": 1024, + "type": "keyword" + }, + "ioctlcmd": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "ignore_above": 1024, + "type": "keyword" + }, + "ipid": { + "ignore_above": 1024, + "type": "keyword" + }, + "ipx-net": { + "ignore_above": 1024, + "type": "keyword" + }, + "items": { + "ignore_above": 1024, + "type": "keyword" + }, + "iuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "ksize": { + "ignore_above": 1024, + "type": "keyword" + }, + "laddr": { + "ignore_above": 1024, + "type": "keyword" + }, + "len": { + "ignore_above": 1024, + "type": "keyword" + }, + "list": { + "ignore_above": 1024, + "type": "keyword" + }, + "lport": { + "ignore_above": 1024, + "type": "keyword" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "macproto": { + "ignore_above": 1024, + "type": "keyword" + }, + "maj": { + "ignore_above": 1024, + "type": "keyword" + }, + "major": { + "ignore_above": 1024, + "type": "keyword" + }, + "minor": { + "ignore_above": 1024, + "type": "keyword" + }, + "model": { + "ignore_above": 1024, + "type": "keyword" + }, + "msg": { + "ignore_above": 1024, + "type": "keyword" + }, + "nargs": { + "ignore_above": 1024, + "type": "keyword" + }, + "net": { + "ignore_above": 1024, + "type": "keyword" + }, + "new": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-chardev": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-disk": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-enabled": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-fs": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-level": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-log_passwd": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-mem": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-net": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-range": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-rng": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-role": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-seuser": { + "ignore_above": 1024, + "type": "keyword" + }, + "new-vcpu": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_lock": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_pe": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_pi": { + "ignore_above": 1024, + "type": "keyword" + }, + "new_pp": { + "ignore_above": 1024, + "type": "keyword" + }, + "nlnk-fam": { + "ignore_above": 1024, + "type": "keyword" + }, + "nlnk-grp": { + "ignore_above": 1024, + "type": "keyword" + }, + "nlnk-pid": { + "ignore_above": 1024, + "type": "keyword" + }, + "oauid": { + "ignore_above": 1024, + "type": "keyword" + }, + "obj": { + "ignore_above": 1024, + "type": "keyword" + }, + "obj_gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "obj_uid": { + "ignore_above": 1024, + "type": "keyword" + }, + "ocomm": { + "ignore_above": 1024, + "type": "keyword" + }, + "oflag": { + "ignore_above": 1024, + "type": "keyword" + }, + "old": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-auid": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-chardev": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-disk": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-enabled": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-fs": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-level": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-log_passwd": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-mem": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-net": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-range": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-rng": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-role": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-ses": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-seuser": { + "ignore_above": 1024, + "type": "keyword" + }, + "old-vcpu": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_enforcing": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_lock": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_pe": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_pi": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_pp": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_prom": { + "ignore_above": 1024, + "type": "keyword" + }, + "old_val": { + "ignore_above": 1024, + "type": "keyword" + }, + "op": { + "ignore_above": 1024, + "type": "keyword" + }, + "opid": { + "ignore_above": 1024, + "type": "keyword" + }, + "oses": { + "ignore_above": 1024, + "type": "keyword" + }, + "outif": { + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "ignore_above": 1024, + "type": "keyword" + }, + "per": { + "ignore_above": 1024, + "type": "keyword" + }, + "perm": { + "ignore_above": 1024, + "type": "keyword" + }, + "perm_mask": { + "ignore_above": 1024, + "type": "keyword" + }, + "permissive": { + "ignore_above": 1024, + "type": "keyword" + }, + "pfs": { + "ignore_above": 1024, + "type": "keyword" + }, + "printer": { + "ignore_above": 1024, + "type": "keyword" + }, + "prom": { + "ignore_above": 1024, + "type": "keyword" + }, + "proto": { + "ignore_above": 1024, + "type": "keyword" + }, + "qbytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "range": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "removed": { + "ignore_above": 1024, + "type": "keyword" + }, + "res": { + "ignore_above": 1024, + "type": "keyword" + }, + "resrc": { + "ignore_above": 1024, + "type": "keyword" + }, + "rport": { + "ignore_above": 1024, + "type": "keyword" + }, + "sauid": { + "ignore_above": 1024, + "type": "keyword" + }, + "scontext": { + "ignore_above": 1024, + "type": "keyword" + }, + "selected-context": { + "ignore_above": 1024, + "type": "keyword" + }, + "seperm": { + "ignore_above": 1024, + "type": "keyword" + }, + "seperms": { + "ignore_above": 1024, + "type": "keyword" + }, + "seqno": { + "ignore_above": 1024, + "type": "keyword" + }, + "seresult": { + "ignore_above": 1024, + "type": "keyword" + }, + "ses": { + "ignore_above": 1024, + "type": "keyword" + }, + "seuser": { + "ignore_above": 1024, + "type": "keyword" + }, + "sig": { + "ignore_above": 1024, + "type": "keyword" + }, + "sigev_signo": { + "ignore_above": 1024, + "type": "keyword" + }, + "smac": { + "ignore_above": 1024, + "type": "keyword" + }, + "socket": { + "properties": { + "addr": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "ignore_above": 1024, + "type": "keyword" + }, + "saddr": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "spid": { + "ignore_above": 1024, + "type": "keyword" + }, + "sport": { + "ignore_above": 1024, + "type": "keyword" + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "subj": { + "ignore_above": 1024, + "type": "keyword" + }, + "success": { + "ignore_above": 1024, + "type": "keyword" + }, + "syscall": { + "ignore_above": 1024, + "type": "keyword" + }, + "table": { + "ignore_above": 1024, + "type": "keyword" + }, + "tclass": { + "ignore_above": 1024, + "type": "keyword" + }, + "tcontext": { + "ignore_above": 1024, + "type": "keyword" + }, + "terminal": { + "ignore_above": 1024, + "type": "keyword" + }, + "tty": { + "ignore_above": 1024, + "type": "keyword" + }, + "unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "uri": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "val": { + "ignore_above": 1024, + "type": "keyword" + }, + "ver": { + "ignore_above": 1024, + "type": "keyword" + }, + "virt": { + "ignore_above": 1024, + "type": "keyword" + }, + "vm": { + "ignore_above": 1024, + "type": "keyword" + }, + "vm-ctx": { + "ignore_above": 1024, + "type": "keyword" + }, + "vm-pid": { + "ignore_above": 1024, + "type": "keyword" + }, + "watch": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "message_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "paths": { + "properties": { + "dev": { + "ignore_above": 1024, + "type": "keyword" + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "item": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "nametype": { + "ignore_above": 1024, + "type": "keyword" + }, + "obj_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "obj_level": { + "ignore_above": 1024, + "type": "keyword" + }, + "obj_role": { + "ignore_above": 1024, + "type": "keyword" + }, + "obj_user": { + "ignore_above": 1024, + "type": "keyword" + }, + "objtype": { + "ignore_above": 1024, + "type": "keyword" + }, + "ogid": { + "ignore_above": 1024, + "type": "keyword" + }, + "ouid": { + "ignore_above": 1024, + "type": "keyword" + }, + "rdev": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "result": { + "ignore_above": 1024, + "type": "keyword" + }, + "sequence": { + "type": "long" + }, + "session": { + "ignore_above": 1024, + "type": "keyword" + }, + "summary": { + "properties": { + "actor": { + "properties": { + "primary": { + "ignore_above": 1024, + "type": "keyword" + }, + "secondary": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "how": { + "ignore_above": 1024, + "type": "keyword" + }, + "object": { + "properties": { + "primary": { + "ignore_above": 1024, + "type": "keyword" + }, + "secondary": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "client": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "container": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "docker": { + "properties": { + "container": { + "properties": { + "labels": { + "type": "object" + } + } + } + } + }, + "ecs": { + "properties": { + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "norms": false, + "type": "text" + }, + "stack_trace": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "ignore_above": 1024, + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "fields": { + "type": "object" + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "fields": { + "raw": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "selinux": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "setgid": { + "type": "boolean" + }, + "setuid": { + "type": "boolean" + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geoip": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "blake2b_256": { + "ignore_above": 1024, + "type": "keyword" + }, + "blake2b_384": { + "ignore_above": 1024, + "type": "keyword" + }, + "blake2b_512": { + "ignore_above": 1024, + "type": "keyword" + }, + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha224": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha3_224": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha3_256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha3_384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha3_512": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512_224": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512_256": { + "ignore_above": 1024, + "type": "keyword" + }, + "xxh64": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "containerized": { + "type": "boolean" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "build": { + "ignore_above": 1024, + "type": "keyword" + }, + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "http": { + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "bytes": { + "type": "long" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "jolokia": { + "properties": { + "agent": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "secured": { + "type": "boolean" + }, + "server": { + "properties": { + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kubernetes": { + "properties": { + "annotations": { + "properties": { + "*": { + "type": "object" + } + } + }, + "container": { + "properties": { + "image": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "deployment": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "properties": { + "*": { + "type": "object" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pod": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "replicaset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "statefulset": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "labels": { + "type": "object" + }, + "log": { + "properties": { + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "original": { + "ignore_above": 1024, + "type": "keyword" + }, + "syslog": { + "properties": { + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "priority": { + "type": "long" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "message": { + "norms": false, + "type": "text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "observer": { + "properties": { + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "hash": { + "properties": { + "blake2b_256": { + "ignore_above": 1024, + "type": "keyword" + }, + "blake2b_384": { + "ignore_above": 1024, + "type": "keyword" + }, + "blake2b_512": { + "ignore_above": 1024, + "type": "keyword" + }, + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha224": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha3_224": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha3_256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha3_384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha3_512": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512_224": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512_256": { + "ignore_above": 1024, + "type": "keyword" + }, + "xxh64": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "command_line": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "ppid": { + "type": "long" + }, + "start": { + "type": "date" + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + }, + "working_directory": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "properties": { + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "socket": { + "properties": { + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "source": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "system": { + "properties": { + "audit": { + "properties": { + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "boottime": { + "type": "date" + }, + "containerized": { + "type": "boolean" + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "codename": { + "ignore_above": 1024, + "type": "keyword" + }, + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "timezone": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "offset": { + "properties": { + "sec": { + "type": "long" + } + } + } + } + }, + "uptime": { + "type": "long" + } + } + }, + "package": { + "properties": { + "arch": { + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "installtime": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "release": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "summary": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "properties": { + "dir": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "type": "object" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "properties": { + "last_changed": { + "type": "date" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "shell": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + }, + "user_information": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "tags": { + "ignore_above": 1024, + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "timeseries": { + "properties": { + "instance": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tracing": { + "properties": { + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "url": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "properties": { + "audit": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "effective": { + "properties": { + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "filesystem": { + "properties": { + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "full_name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "name_map": { + "type": "object" + }, + "saved": { + "properties": { + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "selinux": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "terminal": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user_agent": { + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "norms": false, + "type": "text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "lifecycle": { + "name": "auditbeat", + "rollover_alias": "auditbeat-7.6.2" + }, + "mapping": { + "total_fields": { + "limit": "10000" + } + }, + "number_of_replicas": "1", + "number_of_shards": "1", + "query": { + "default_field": [ + "message", + "tags", + "agent.ephemeral_id", + "agent.id", + "agent.name", + "agent.type", + "agent.version", + "as.organization.name", + "client.address", + "client.as.organization.name", + "client.domain", + "client.geo.city_name", + "client.geo.continent_name", + "client.geo.country_iso_code", + "client.geo.country_name", + "client.geo.name", + "client.geo.region_iso_code", + "client.geo.region_name", + "client.mac", + "client.registered_domain", + "client.top_level_domain", + "client.user.domain", + "client.user.email", + "client.user.full_name", + "client.user.group.domain", + "client.user.group.id", + "client.user.group.name", + "client.user.hash", + "client.user.id", + "client.user.name", + "cloud.account.id", + "cloud.availability_zone", + "cloud.instance.id", + "cloud.instance.name", + "cloud.machine.type", + "cloud.provider", + "cloud.region", + "container.id", + "container.image.name", + "container.image.tag", + "container.name", + "container.runtime", + "destination.address", + "destination.as.organization.name", + "destination.domain", + "destination.geo.city_name", + "destination.geo.continent_name", + "destination.geo.country_iso_code", + "destination.geo.country_name", + "destination.geo.name", + "destination.geo.region_iso_code", + "destination.geo.region_name", + "destination.mac", + "destination.registered_domain", + "destination.top_level_domain", + "destination.user.domain", + "destination.user.email", + "destination.user.full_name", + "destination.user.group.domain", + "destination.user.group.id", + "destination.user.group.name", + "destination.user.hash", + "destination.user.id", + "destination.user.name", + "dns.answers.class", + "dns.answers.data", + "dns.answers.name", + "dns.answers.type", + "dns.header_flags", + "dns.id", + "dns.op_code", + "dns.question.class", + "dns.question.name", + "dns.question.registered_domain", + "dns.question.subdomain", + "dns.question.top_level_domain", + "dns.question.type", + "dns.response_code", + "dns.type", + "ecs.version", + "error.code", + "error.id", + "error.message", + "error.stack_trace", + "error.type", + "event.action", + "event.category", + "event.code", + "event.dataset", + "event.hash", + "event.id", + "event.kind", + "event.module", + "event.original", + "event.outcome", + "event.provider", + "event.timezone", + "event.type", + "file.device", + "file.directory", + "file.extension", + "file.gid", + "file.group", + "file.hash.md5", + "file.hash.sha1", + "file.hash.sha256", + "file.hash.sha512", + "file.inode", + "file.mode", + "file.name", + "file.owner", + "file.path", + "file.target_path", + "file.type", + "file.uid", + "geo.city_name", + "geo.continent_name", + "geo.country_iso_code", + "geo.country_name", + "geo.name", + "geo.region_iso_code", + "geo.region_name", + "group.domain", + "group.id", + "group.name", + "hash.md5", + "hash.sha1", + "hash.sha256", + "hash.sha512", + "host.architecture", + "host.geo.city_name", + "host.geo.continent_name", + "host.geo.country_iso_code", + "host.geo.country_name", + "host.geo.name", + "host.geo.region_iso_code", + "host.geo.region_name", + "host.hostname", + "host.id", + "host.mac", + "host.name", + "host.os.family", + "host.os.full", + "host.os.kernel", + "host.os.name", + "host.os.platform", + "host.os.version", + "host.type", + "host.user.domain", + "host.user.email", + "host.user.full_name", + "host.user.group.domain", + "host.user.group.id", + "host.user.group.name", + "host.user.hash", + "host.user.id", + "host.user.name", + "http.request.body.content", + "http.request.method", + "http.request.referrer", + "http.response.body.content", + "http.version", + "log.level", + "log.logger", + "log.origin.file.name", + "log.origin.function", + "log.original", + "log.syslog.facility.name", + "log.syslog.severity.name", + "network.application", + "network.community_id", + "network.direction", + "network.iana_number", + "network.name", + "network.protocol", + "network.transport", + "network.type", + "observer.geo.city_name", + "observer.geo.continent_name", + "observer.geo.country_iso_code", + "observer.geo.country_name", + "observer.geo.name", + "observer.geo.region_iso_code", + "observer.geo.region_name", + "observer.hostname", + "observer.mac", + "observer.name", + "observer.os.family", + "observer.os.full", + "observer.os.kernel", + "observer.os.name", + "observer.os.platform", + "observer.os.version", + "observer.product", + "observer.serial_number", + "observer.type", + "observer.vendor", + "observer.version", + "organization.id", + "organization.name", + "os.family", + "os.full", + "os.kernel", + "os.name", + "os.platform", + "os.version", + "package.architecture", + "package.checksum", + "package.description", + "package.install_scope", + "package.license", + "package.name", + "package.path", + "package.version", + "process.args", + "text", + "process.executable", + "process.hash.md5", + "process.hash.sha1", + "process.hash.sha256", + "process.hash.sha512", + "process.name", + "text", + "text", + "text", + "text", + "text", + "process.thread.name", + "process.title", + "process.working_directory", + "server.address", + "server.as.organization.name", + "server.domain", + "server.geo.city_name", + "server.geo.continent_name", + "server.geo.country_iso_code", + "server.geo.country_name", + "server.geo.name", + "server.geo.region_iso_code", + "server.geo.region_name", + "server.mac", + "server.registered_domain", + "server.top_level_domain", + "server.user.domain", + "server.user.email", + "server.user.full_name", + "server.user.group.domain", + "server.user.group.id", + "server.user.group.name", + "server.user.hash", + "server.user.id", + "server.user.name", + "service.ephemeral_id", + "service.id", + "service.name", + "service.node.name", + "service.state", + "service.type", + "service.version", + "source.address", + "source.as.organization.name", + "source.domain", + "source.geo.city_name", + "source.geo.continent_name", + "source.geo.country_iso_code", + "source.geo.country_name", + "source.geo.name", + "source.geo.region_iso_code", + "source.geo.region_name", + "source.mac", + "source.registered_domain", + "source.top_level_domain", + "source.user.domain", + "source.user.email", + "source.user.full_name", + "source.user.group.domain", + "source.user.group.id", + "source.user.group.name", + "source.user.hash", + "source.user.id", + "source.user.name", + "threat.framework", + "threat.tactic.id", + "threat.tactic.name", + "threat.tactic.reference", + "threat.technique.id", + "threat.technique.name", + "threat.technique.reference", + "tracing.trace.id", + "tracing.transaction.id", + "url.domain", + "url.extension", + "url.fragment", + "url.full", + "url.original", + "url.password", + "url.path", + "url.query", + "url.registered_domain", + "url.scheme", + "url.top_level_domain", + "url.username", + "user.domain", + "user.email", + "user.full_name", + "user.group.domain", + "user.group.id", + "user.group.name", + "user.hash", + "user.id", + "user.name", + "user_agent.device.name", + "user_agent.name", + "text", + "user_agent.original", + "user_agent.os.family", + "user_agent.os.full", + "user_agent.os.kernel", + "user_agent.os.name", + "user_agent.os.platform", + "user_agent.os.version", + "user_agent.version", + "text", + "agent.hostname", + "timeseries.instance", + "cloud.project.id", + "cloud.image.id", + "host.os.build", + "host.os.codename", + "kubernetes.pod.name", + "kubernetes.pod.uid", + "kubernetes.namespace", + "kubernetes.node.name", + "kubernetes.replicaset.name", + "kubernetes.deployment.name", + "kubernetes.statefulset.name", + "kubernetes.container.name", + "kubernetes.container.image", + "jolokia.agent.version", + "jolokia.agent.id", + "jolokia.server.product", + "jolokia.server.version", + "jolokia.server.vendor", + "jolokia.url", + "raw", + "file.origin", + "file.selinux.user", + "file.selinux.role", + "file.selinux.domain", + "file.selinux.level", + "user.audit.id", + "user.audit.name", + "user.effective.id", + "user.effective.name", + "user.effective.group.id", + "user.effective.group.name", + "user.filesystem.id", + "user.filesystem.name", + "user.filesystem.group.id", + "user.filesystem.group.name", + "user.saved.id", + "user.saved.name", + "user.saved.group.id", + "user.saved.group.name", + "user.selinux.user", + "user.selinux.role", + "user.selinux.domain", + "user.selinux.level", + "user.selinux.category", + "source.path", + "destination.path", + "auditd.message_type", + "auditd.session", + "auditd.result", + "auditd.summary.actor.primary", + "auditd.summary.actor.secondary", + "auditd.summary.object.type", + "auditd.summary.object.primary", + "auditd.summary.object.secondary", + "auditd.summary.how", + "auditd.paths.inode", + "auditd.paths.dev", + "auditd.paths.obj_user", + "auditd.paths.obj_role", + "auditd.paths.obj_domain", + "auditd.paths.obj_level", + "auditd.paths.objtype", + "auditd.paths.ouid", + "auditd.paths.rdev", + "auditd.paths.nametype", + "auditd.paths.ogid", + "auditd.paths.item", + "auditd.paths.mode", + "auditd.paths.name", + "auditd.data.action", + "auditd.data.minor", + "auditd.data.acct", + "auditd.data.addr", + "auditd.data.cipher", + "auditd.data.id", + "auditd.data.entries", + "auditd.data.kind", + "auditd.data.ksize", + "auditd.data.spid", + "auditd.data.arch", + "auditd.data.argc", + "auditd.data.major", + "auditd.data.unit", + "auditd.data.table", + "auditd.data.terminal", + "auditd.data.grantors", + "auditd.data.direction", + "auditd.data.op", + "auditd.data.tty", + "auditd.data.syscall", + "auditd.data.data", + "auditd.data.family", + "auditd.data.mac", + "auditd.data.pfs", + "auditd.data.items", + "auditd.data.a0", + "auditd.data.a1", + "auditd.data.a2", + "auditd.data.a3", + "auditd.data.hostname", + "auditd.data.lport", + "auditd.data.rport", + "auditd.data.exit", + "auditd.data.fp", + "auditd.data.laddr", + "auditd.data.sport", + "auditd.data.capability", + "auditd.data.nargs", + "auditd.data.new-enabled", + "auditd.data.audit_backlog_limit", + "auditd.data.dir", + "auditd.data.cap_pe", + "auditd.data.model", + "auditd.data.new_pp", + "auditd.data.old-enabled", + "auditd.data.oauid", + "auditd.data.old", + "auditd.data.banners", + "auditd.data.feature", + "auditd.data.vm-ctx", + "auditd.data.opid", + "auditd.data.seperms", + "auditd.data.seresult", + "auditd.data.new-rng", + "auditd.data.old-net", + "auditd.data.sigev_signo", + "auditd.data.ino", + "auditd.data.old_enforcing", + "auditd.data.old-vcpu", + "auditd.data.range", + "auditd.data.res", + "auditd.data.added", + "auditd.data.fam", + "auditd.data.nlnk-pid", + "auditd.data.subj", + "auditd.data.a[0-3]", + "auditd.data.cgroup", + "auditd.data.kernel", + "auditd.data.ocomm", + "auditd.data.new-net", + "auditd.data.permissive", + "auditd.data.class", + "auditd.data.compat", + "auditd.data.fi", + "auditd.data.changed", + "auditd.data.msg", + "auditd.data.dport", + "auditd.data.new-seuser", + "auditd.data.invalid_context", + "auditd.data.dmac", + "auditd.data.ipx-net", + "auditd.data.iuid", + "auditd.data.macproto", + "auditd.data.obj", + "auditd.data.ipid", + "auditd.data.new-fs", + "auditd.data.vm-pid", + "auditd.data.cap_pi", + "auditd.data.old-auid", + "auditd.data.oses", + "auditd.data.fd", + "auditd.data.igid", + "auditd.data.new-disk", + "auditd.data.parent", + "auditd.data.len", + "auditd.data.oflag", + "auditd.data.uuid", + "auditd.data.code", + "auditd.data.nlnk-grp", + "auditd.data.cap_fp", + "auditd.data.new-mem", + "auditd.data.seperm", + "auditd.data.enforcing", + "auditd.data.new-chardev", + "auditd.data.old-rng", + "auditd.data.outif", + "auditd.data.cmd", + "auditd.data.hook", + "auditd.data.new-level", + "auditd.data.sauid", + "auditd.data.sig", + "auditd.data.audit_backlog_wait_time", + "auditd.data.printer", + "auditd.data.old-mem", + "auditd.data.perm", + "auditd.data.old_pi", + "auditd.data.state", + "auditd.data.format", + "auditd.data.new_gid", + "auditd.data.tcontext", + "auditd.data.maj", + "auditd.data.watch", + "auditd.data.device", + "auditd.data.grp", + "auditd.data.bool", + "auditd.data.icmp_type", + "auditd.data.new_lock", + "auditd.data.old_prom", + "auditd.data.acl", + "auditd.data.ip", + "auditd.data.new_pi", + "auditd.data.default-context", + "auditd.data.inode_gid", + "auditd.data.new-log_passwd", + "auditd.data.new_pe", + "auditd.data.selected-context", + "auditd.data.cap_fver", + "auditd.data.file", + "auditd.data.net", + "auditd.data.virt", + "auditd.data.cap_pp", + "auditd.data.old-range", + "auditd.data.resrc", + "auditd.data.new-range", + "auditd.data.obj_gid", + "auditd.data.proto", + "auditd.data.old-disk", + "auditd.data.audit_failure", + "auditd.data.inif", + "auditd.data.vm", + "auditd.data.flags", + "auditd.data.nlnk-fam", + "auditd.data.old-fs", + "auditd.data.old-ses", + "auditd.data.seqno", + "auditd.data.fver", + "auditd.data.qbytes", + "auditd.data.seuser", + "auditd.data.cap_fe", + "auditd.data.new-vcpu", + "auditd.data.old-level", + "auditd.data.old_pp", + "auditd.data.daddr", + "auditd.data.old-role", + "auditd.data.ioctlcmd", + "auditd.data.smac", + "auditd.data.apparmor", + "auditd.data.fe", + "auditd.data.perm_mask", + "auditd.data.ses", + "auditd.data.cap_fi", + "auditd.data.obj_uid", + "auditd.data.reason", + "auditd.data.list", + "auditd.data.old_lock", + "auditd.data.bus", + "auditd.data.old_pe", + "auditd.data.new-role", + "auditd.data.prom", + "auditd.data.uri", + "auditd.data.audit_enabled", + "auditd.data.old-log_passwd", + "auditd.data.old-seuser", + "auditd.data.per", + "auditd.data.scontext", + "auditd.data.tclass", + "auditd.data.ver", + "auditd.data.new", + "auditd.data.val", + "auditd.data.img-ctx", + "auditd.data.old-chardev", + "auditd.data.old_val", + "auditd.data.success", + "auditd.data.inode_uid", + "auditd.data.removed", + "auditd.data.socket.port", + "auditd.data.socket.saddr", + "auditd.data.socket.addr", + "auditd.data.socket.family", + "auditd.data.socket.path", + "geoip.continent_name", + "geoip.city_name", + "geoip.region_name", + "geoip.country_iso_code", + "hash.blake2b_256", + "hash.blake2b_384", + "hash.blake2b_512", + "hash.md5", + "hash.sha1", + "hash.sha224", + "hash.sha256", + "hash.sha384", + "hash.sha3_224", + "hash.sha3_256", + "hash.sha3_384", + "hash.sha3_512", + "hash.sha512", + "hash.sha512_224", + "hash.sha512_256", + "hash.xxh64", + "event.origin", + "user.entity_id", + "user.terminal", + "process.entity_id", + "process.hash.blake2b_256", + "process.hash.blake2b_384", + "process.hash.blake2b_512", + "process.hash.sha224", + "process.hash.sha384", + "process.hash.sha3_224", + "process.hash.sha3_256", + "process.hash.sha3_384", + "process.hash.sha3_512", + "process.hash.sha512_224", + "process.hash.sha512_256", + "process.hash.xxh64", + "socket.entity_id", + "system.audit.host.timezone.name", + "system.audit.host.hostname", + "system.audit.host.id", + "system.audit.host.architecture", + "system.audit.host.mac", + "system.audit.host.os.codename", + "system.audit.host.os.platform", + "system.audit.host.os.name", + "system.audit.host.os.family", + "system.audit.host.os.version", + "system.audit.host.os.kernel", + "system.audit.package.entity_id", + "system.audit.package.name", + "system.audit.package.version", + "system.audit.package.release", + "system.audit.package.arch", + "system.audit.package.license", + "system.audit.package.summary", + "system.audit.package.url", + "system.audit.user.name", + "system.audit.user.uid", + "system.audit.user.gid", + "system.audit.user.dir", + "system.audit.user.shell", + "system.audit.user.user_information", + "system.audit.user.password.type", + "fields.*" + ] + }, + "refresh_interval": "5s" + } + } + } +} \ No newline at end of file From 0bdcda8f20c1ac4e69a6829860d607d90d0a3d3b Mon Sep 17 00:00:00 2001 From: Garrett Spong Date: Mon, 6 Apr 2020 13:44:46 -0600 Subject: [PATCH 3/8] [SIEM] Fixes UX issues around prebuilt ML Rules (#62396) ## Summary This PR fixes a number of UX issues around the new prebuilt `machine_learning` rules when the user does not have the necessary permissions to manage the backing ML Job. Along with https://github.com/elastic/kibana/pull/62383, this ensures there is adequate information for the user determine if a rule is not working because the backing job is not running (and helping to prevent this from occurring). This also includes some requested copy changes, including: * Renames `Anomaly Detection` dropdown to `ML job settings`

* Updates copy in `ML job settings` dropdown

* Only shows `ML job settings` UI when on `/detections/` routes

### All Rules Changes * Disables the `activate switch` if user does not have permission to enable/disable jobs

* Adds warning toast when attempting to activate via bulk actions (if user does not have permission to enable/disable jobs)

### Rule Details Changes * `Machine Learning job` link now links to ML App with table filtered to the relevant job * Disables the `activate switch` if user does not have permission to enable/disable jobs

### Create/Edit Rule Changes * If the job selected _is not running_, a warning will be displayed to remind the user to enable the job before running the rule. cc @benskelker @MikePaquette -- this okay copy here?

Resolves https://github.com/elastic/siem-team/issues/575 Resolves https://github.com/elastic/siem-team/issues/519 ### Checklist Delete any items that are not applicable to this PR. - [X] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md) - [ ] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials - Scheduled time with @benskelker to update docs - [X] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- .../components/header_global/index.test.tsx | 14 +++ .../public/components/header_global/index.tsx | 116 +++++++++--------- .../popover_description.test.tsx.snap | 2 +- .../components/ml_popover/ml_popover.tsx | 6 +- .../ml_popover/popover_description.tsx | 2 +- .../components/ml_popover/translations.ts | 13 +- .../siem/public/components/toasters/utils.ts | 24 ++++ .../rules/all/batch_actions.tsx | 22 +++- .../detection_engine/rules/all/columns.tsx | 32 +++-- .../detection_engine/rules/all/index.tsx | 29 ++++- .../description_step/ml_job_description.tsx | 4 +- .../rules/components/ml_job_select/index.tsx | 112 +++++++++++------ .../step_define_rule/translations.tsx | 8 ++ .../detection_engine/rules/details/index.tsx | 34 +++-- .../pages/detection_engine/translations.ts | 14 +++ .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 17 files changed, 305 insertions(+), 131 deletions(-) diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx index 098de39bbfef5..56fa0d56f3c3a 100644 --- a/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.test.tsx @@ -10,6 +10,16 @@ import React from 'react'; import '../../mock/match_media'; import { HeaderGlobal } from './index'; +jest.mock('react-router-dom', () => ({ + useLocation: () => ({ + pathname: '/app/siem#/hosts/allHosts', + hash: '', + search: '', + state: '', + }), + withRouter: () => jest.fn(), +})); + jest.mock('ui/new_platform'); // Test will fail because we will to need to mock some core services to make the test work @@ -19,6 +29,10 @@ jest.mock('../search_bar', () => ({ })); describe('HeaderGlobal', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + test('it renders', () => { const wrapper = shallow(); diff --git a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx index a12fab8a4f5d9..adc2be4f9c365 100644 --- a/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/header_global/index.tsx @@ -9,6 +9,7 @@ import { pickBy } from 'lodash/fp'; import React from 'react'; import styled, { css } from 'styled-components'; +import { useLocation } from 'react-router-dom'; import { gutterTimeline } from '../../lib/helpers'; import { navTabs } from '../../pages/home/home_navigations'; import { SiemPageName } from '../../pages/home/types'; @@ -36,63 +37,68 @@ FlexItem.displayName = 'FlexItem'; interface HeaderGlobalProps { hideDetectionEngine?: boolean; } -export const HeaderGlobal = React.memo(({ hideDetectionEngine = false }) => ( - - - - {({ indicesExist }) => ( - <> - - - - - - - +export const HeaderGlobal = React.memo(({ hideDetectionEngine = false }) => { + const currentLocation = useLocation(); - - {indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( - key !== SiemPageName.detections, navTabs) - : navTabs - } - /> - ) : ( - key === SiemPageName.overview, navTabs)} - /> - )} - - - - - - - {indicesExistOrDataTemporarilyUnavailable(indicesExist) && ( + return ( + + + + {({ indicesExist }) => ( + <> + + - + + + + + + + {indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( + key !== SiemPageName.detections, navTabs) + : navTabs + } + /> + ) : ( + key === SiemPageName.overview, navTabs)} + /> + )} - )} + + - - - {i18n.BUTTON_ADD_DATA} - - - - - - )} - - - -)); + + + {indicesExistOrDataTemporarilyUnavailable(indicesExist) && + currentLocation.pathname.includes(`/${SiemPageName.detections}/`) && ( + + + + )} + + + + {i18n.BUTTON_ADD_DATA} + + + + + + )} + + + + ); +}); HeaderGlobal.displayName = 'HeaderGlobal'; diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/__snapshots__/popover_description.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/ml_popover/__snapshots__/popover_description.test.tsx.snap index 09e95c5ff59ea..46e61f9e939ee 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/__snapshots__/popover_description.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/__snapshots__/popover_description.test.tsx.snap @@ -5,7 +5,7 @@ exports[`JobsTableFilters renders correctly against snapshot 1`] = ` size="s" > { iconSide="right" onClick={() => setIsPopoverOpen(!isPopoverOpen)} > - {i18n.ANOMALY_DETECTION} + {i18n.ML_JOB_SETTINGS} } isOpen={isPopoverOpen} @@ -142,14 +142,14 @@ export const MlPopover = React.memo(() => { dispatch({ type: 'refresh' }); }} > - {i18n.ANOMALY_DETECTION} + {i18n.ML_JOB_SETTINGS} } isOpen={isPopoverOpen} closePopover={() => setIsPopoverOpen(!isPopoverOpen)} > - {i18n.ANOMALY_DETECTION_TITLE} + {i18n.ML_JOB_SETTINGS} diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.tsx index 20e8dd2492fef..a491d4b6b769c 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/popover_description.tsx @@ -14,7 +14,7 @@ export const PopoverDescriptionComponent = () => ( diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/translations.ts b/x-pack/legacy/plugins/siem/public/components/ml_popover/translations.ts index 442068dd0e193..613691e55dcfd 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/translations.ts +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/translations.ts @@ -6,17 +6,10 @@ import { i18n } from '@kbn/i18n'; -export const ANOMALY_DETECTION = i18n.translate( - 'xpack.siem.components.mlPopup.anomalyDetectionButtonLabel', +export const ML_JOB_SETTINGS = i18n.translate( + 'xpack.siem.components.mlPopup.mlJobSettingsButtonLabel', { - defaultMessage: 'Anomaly detection', - } -); - -export const ANOMALY_DETECTION_TITLE = i18n.translate( - 'xpack.siem.components.mlPopup.anomalyDetectionTitle', - { - defaultMessage: 'Anomaly detection settings', + defaultMessage: 'ML job settings', } ); diff --git a/x-pack/legacy/plugins/siem/public/components/toasters/utils.ts b/x-pack/legacy/plugins/siem/public/components/toasters/utils.ts index e624144c9826f..e7cc389d4c06b 100644 --- a/x-pack/legacy/plugins/siem/public/components/toasters/utils.ts +++ b/x-pack/legacy/plugins/siem/public/components/toasters/utils.ts @@ -37,6 +37,30 @@ export const displayErrorToast = ( }); }; +/** + * Displays a warning toast for the provided title and message + * + * @param title warning message to display in toaster and modal + * @param dispatchToaster provided by useStateToaster() + * @param id unique ID if necessary + */ +export const displayWarningToast = ( + title: string, + dispatchToaster: React.Dispatch, + id: string = uuid.v4() +): void => { + const toast: AppToast = { + id, + title, + color: 'warning', + iconType: 'help', + }; + dispatchToaster({ + type: 'addToaster', + toast, + }); +}; + /** * Displays a success toast for the provided title and message * diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx index 60ad68b8c9141..454ef18e0ae14 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx @@ -14,13 +14,15 @@ import { enableRulesAction, exportRulesAction, } from './actions'; -import { ActionToaster } from '../../../../components/toasters'; +import { ActionToaster, displayWarningToast } from '../../../../components/toasters'; import { Rule } from '../../../../containers/detection_engine/rules'; +import * as detectionI18n from '../../translations'; interface GetBatchItems { closePopover: () => void; dispatch: Dispatch; dispatchToaster: Dispatch; + hasMlPermissions: boolean; loadingRuleIds: string[]; reFetchRules: (refreshPrePackagedRule?: boolean) => void; rules: Rule[]; @@ -31,6 +33,7 @@ export const getBatchItems = ({ closePopover, dispatch, dispatchToaster, + hasMlPermissions, loadingRuleIds, reFetchRules, rules, @@ -57,7 +60,22 @@ export const getBatchItems = ({ const deactivatedIds = selectedRuleIds.filter( id => !rules.find(r => r.id === id)?.enabled ?? false ); - await enableRulesAction(deactivatedIds, true, dispatch, dispatchToaster); + + const deactivatedIdsNoML = deactivatedIds.filter( + id => rules.find(r => r.id === id)?.type !== 'machine_learning' ?? false + ); + + const mlRuleCount = deactivatedIds.length - deactivatedIdsNoML.length; + if (!hasMlPermissions && mlRuleCount > 0) { + displayWarningToast(detectionI18n.ML_RULES_UNAVAILABLE(mlRuleCount), dispatchToaster); + } + + await enableRulesAction( + hasMlPermissions ? deactivatedIds : deactivatedIdsNoML, + true, + dispatch, + dispatchToaster + ); }} > {i18n.BATCH_ACTION_ACTIVATE_SELECTED} diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx index 9a84d33ab5fdf..80e644f800334 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx @@ -13,6 +13,7 @@ import { EuiTableActionsColumnType, EuiText, EuiHealth, + EuiToolTip, } from '@elastic/eui'; import { FormattedRelative } from '@kbn/i18n/react'; import * as H from 'history'; @@ -36,6 +37,8 @@ import { } from './actions'; import { Action } from './reducer'; import { LocalizedDateTooltip } from '../../../../components/localized_date_tooltip'; +import * as detectionI18n from '../../translations'; +import { isMlRule } from '../../../../../common/detection_engine/ml_helpers'; export const getActions = ( dispatch: React.Dispatch, @@ -88,6 +91,7 @@ interface GetColumns { dispatch: React.Dispatch; dispatchToaster: Dispatch; history: H.History; + hasMlPermissions: boolean; hasNoPermissions: boolean; loadingRuleIds: string[]; reFetchRules: (refreshPrePackagedRule?: boolean) => void; @@ -98,6 +102,7 @@ export const getColumns = ({ dispatch, dispatchToaster, history, + hasMlPermissions, hasNoPermissions, loadingRuleIds, reFetchRules, @@ -182,14 +187,25 @@ export const getColumns = ({ field: 'enabled', name: i18n.COLUMN_ACTIVATE, render: (value: Rule['enabled'], item: Rule) => ( - + + + ), sortable: true, width: '95px', diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx index ccdfd1ed1be38..e96ed856208bd 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx @@ -40,6 +40,8 @@ import { getColumns, getMonitoringColumns } from './columns'; import { showRulesTable } from './helpers'; import { allRulesReducer, State } from './reducer'; import { RulesTableFilters } from './rules_table_filters/rules_table_filters'; +import { useMlCapabilities } from '../../../../components/ml_popover/hooks/use_ml_capabilities'; +import { hasMlAdminPermissions } from '../../../../components/ml/permissions/has_ml_admin_permissions'; const SORT_FIELD = 'enabled'; const initialState: State = { @@ -111,6 +113,11 @@ export const AllRules = React.memo( const { loading: isLoadingRulesStatuses, rulesStatuses } = useRulesStatuses(rules); const history = useHistory(); const [, dispatchToaster] = useStateToaster(); + const mlCapabilities = useMlCapabilities(); + + // TODO: Refactor license check + hasMlAdminPermissions to common check + const hasMlPermissions = + mlCapabilities.isPlatinumOrTrialLicense && hasMlAdminPermissions(mlCapabilities); const setRules = useCallback((newRules: Rule[], newPagination: Partial) => { dispatch({ @@ -145,6 +152,7 @@ export const AllRules = React.memo( closePopover, dispatch, dispatchToaster, + hasMlPermissions, loadingRuleIds, selectedRuleIds, reFetchRules: reFetchRulesData, @@ -152,7 +160,15 @@ export const AllRules = React.memo( })} /> ), - [dispatch, dispatchToaster, loadingRuleIds, reFetchRulesData, rules, selectedRuleIds] + [ + dispatch, + dispatchToaster, + hasMlPermissions, + loadingRuleIds, + reFetchRulesData, + rules, + selectedRuleIds, + ] ); const paginationMemo = useMemo( @@ -184,6 +200,7 @@ export const AllRules = React.memo( dispatch, dispatchToaster, history, + hasMlPermissions, hasNoPermissions, loadingRuleIds: loadingRulesAction != null && @@ -192,7 +209,15 @@ export const AllRules = React.memo( : [], reFetchRules: reFetchRulesData, }); - }, [dispatch, dispatchToaster, history, loadingRuleIds, loadingRulesAction, reFetchRulesData]); + }, [ + dispatch, + dispatchToaster, + hasMlPermissions, + history, + loadingRuleIds, + loadingRulesAction, + reFetchRulesData, + ]); const monitoringColumns = useMemo(() => getMonitoringColumns(), []); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.tsx index 8276aa3578563..5a9593f1a6de2 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/description_step/ml_job_description.tsx @@ -66,7 +66,9 @@ const Wrapper = styled.div` `; export const MlJobDescription: React.FC<{ job: SiemJob }> = ({ job }) => { - const jobUrl = useKibana().services.application.getUrlForApp('ml#/jobs'); + const jobUrl = useKibana().services.application.getUrlForApp( + `ml#/jobs?mlManagement=(jobId:${encodeURI(job.id)})` + ); return ( diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/ml_job_select/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/ml_job_select/index.tsx index 3d253b71b53d6..794edf0ab5de7 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/ml_job_select/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/ml_job_select/index.tsx @@ -4,37 +4,64 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useCallback } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFlexGroup, EuiFlexItem, EuiFormRow, + EuiIcon, EuiLink, EuiSuperSelect, EuiText, } from '@elastic/eui'; +import styled from 'styled-components'; import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../../shared_imports'; import { useSiemJobs } from '../../../../../components/ml_popover/hooks/use_siem_jobs'; import { useKibana } from '../../../../../lib/kibana'; -import { ML_JOB_SELECT_PLACEHOLDER_TEXT } from '../step_define_rule/translations'; +import { + ML_JOB_SELECT_PLACEHOLDER_TEXT, + ENABLE_ML_JOB_WARNING, +} from '../step_define_rule/translations'; +import { isJobStarted } from '../../../../../../common/detection_engine/ml_helpers'; + +const HelpTextWarningContainer = styled.div` + margin-top: 10px; +`; + +const MlJobSelectEuiFlexGroup = styled(EuiFlexGroup)` + margin-bottom: 5px; +`; -const HelpText: React.FC<{ href: string }> = ({ href }) => ( - - - - ), - }} - /> +const HelpText: React.FC<{ href: string; showEnableWarning: boolean }> = ({ + href, + showEnableWarning = false, +}) => ( + <> + + + + ), + }} + /> + {showEnableWarning && ( + + + + {ENABLE_ML_JOB_WARNING} + + + )} + ); const JobDisplay: React.FC<{ title: string; description: string }> = ({ title, description }) => ( @@ -77,26 +104,37 @@ export const MlJobSelect: React.FC = ({ describedByIds = [], f const options = [placeholderOption, ...jobOptions]; + const isJobRunning = useMemo(() => { + // If the selected job is not found in the list, it means the placeholder is selected + // and so we don't want to show the warning, thus isJobRunning will be true when 'job == null' + const job = siemJobs.find(j => j.id === jobId); + return job == null || isJobStarted(job.jobState, job.datafeedState); + }, [siemJobs, jobId]); + return ( - } - isInvalid={isInvalid} - error={errorMessage} - data-test-subj="mlJobSelect" - describedByIds={describedByIds} - > - - - - - - + + + } + isInvalid={isInvalid} + error={errorMessage} + data-test-subj="mlJobSelect" + describedByIds={describedByIds} + > + + + + + + + + ); }; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/translations.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/translations.tsx index 1d8821aceb249..bbdb2130ce298 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/translations.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/translations.tsx @@ -62,3 +62,11 @@ export const ML_JOB_SELECT_PLACEHOLDER_TEXT = i18n.translate( defaultMessage: 'Select a job', } ); + +export const ENABLE_ML_JOB_WARNING = i18n.translate( + 'xpack.siem.detectionEngine.createRule.stepDefineRule.mlEnableJobWarningTitle', + { + defaultMessage: + 'This ML job is not currently running. Please set this job to run via "ML job settings" before activating this rule.', + } +); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx index cb4d88a8bb539..2b648a3b3f825 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/details/index.tsx @@ -14,6 +14,7 @@ import { EuiSpacer, EuiTab, EuiTabs, + EuiToolTip, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import React, { FC, memo, useCallback, useMemo, useState } from 'react'; @@ -66,6 +67,8 @@ import { RuleActionsOverflow } from '../components/rule_actions_overflow'; import { RuleStatusFailedCallOut } from './status_failed_callout'; import { FailureHistory } from './failure_history'; import { RuleStatus } from '../components/rule_status'; +import { useMlCapabilities } from '../../../../components/ml_popover/hooks/use_ml_capabilities'; +import { hasMlAdminPermissions } from '../../../../components/ml/permissions/has_ml_admin_permissions'; enum RuleDetailTabs { signals = 'signals', @@ -114,6 +117,11 @@ const RuleDetailsPageComponent: FC = ({ scheduleRuleData: null, }; const [lastSignals] = useSignalInfo({ ruleId }); + const mlCapabilities = useMlCapabilities(); + + // TODO: Refactor license check + hasMlAdminPermissions to common check + const hasMlPermissions = + mlCapabilities.isPlatinumOrTrialLicense && hasMlAdminPermissions(mlCapabilities); const title = isLoading === true || rule === null ? : rule.name; const subTitle = useMemo( @@ -259,13 +267,25 @@ const RuleDetailsPageComponent: FC = ({ > - + + + diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts index 39277b3d3c77e..008d660be9d88 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/translations.ts @@ -86,3 +86,17 @@ export const USER_UNAUTHENTICATED_MSG_BODY = i18n.translate( 'You do not have the required permissions for viewing the detection engine. For more help, contact your administrator.', } ); + +export const ML_RULES_DISABLED_MESSAGE = i18n.translate( + 'xpack.siem.detectionEngine.mlRulesDisabledMessageTitle', + { + defaultMessage: 'ML rules require Platinum License and ML Admin Permissions', + } +); + +export const ML_RULES_UNAVAILABLE = (totalRules: number) => + i18n.translate('xpack.siem.detectionEngine.mlUnavailableTitle', { + values: { totalRules }, + defaultMessage: + '{totalRules} {totalRules, plural, =1 {rule requires} other {rules require}} Machine Learning to enable.', + }); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 023a97274b957..79c1bbc49810b 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -13548,9 +13548,7 @@ "xpack.siem.components.mlPopover.jobsTable.filters.searchFilterPlaceholder": "例: rare_process_linux", "xpack.siem.components.mlPopover.jobsTable.filters.showAllJobsLabel": "Elastic ジョブ", "xpack.siem.components.mlPopover.jobsTable.filters.showSiemJobsLabel": "カスタムジョブ", - "xpack.siem.components.mlPopup.anomalyDetectionButtonLabel": "異常検知", "xpack.siem.components.mlPopup.anomalyDetectionDescription": "下のいずれかの機械学習ジョブを実行して、SIEM アプリケーション全体の異常イベントを表示することができます。始めに使えるように、いくつかの一般的な検出ジョブが提供されています。独自のカスタムジョブを追加する場合は、{machineLearning} アプリケーションでジョブを作成して「SIEM」でタグ付けすると、ここに追加されます。", - "xpack.siem.components.mlPopup.anomalyDetectionTitle": "異常検知設定", "xpack.siem.components.mlPopup.cloudLink": "クラウド展開", "xpack.siem.components.mlPopup.errors.createJobFailureTitle": "ジョブ作成エラー", "xpack.siem.components.mlPopup.errors.startJobFailureTitle": "ジョブ開始エラー", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index b359014e95e70..77bf8f1467783 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -13552,9 +13552,7 @@ "xpack.siem.components.mlPopover.jobsTable.filters.searchFilterPlaceholder": "例如 rare_process_linux", "xpack.siem.components.mlPopover.jobsTable.filters.showAllJobsLabel": "Elastic 作业", "xpack.siem.components.mlPopover.jobsTable.filters.showSiemJobsLabel": "定制作业", - "xpack.siem.components.mlPopup.anomalyDetectionButtonLabel": "异常检测", "xpack.siem.components.mlPopup.anomalyDetectionDescription": "运行以下任何 Machine Learning 作业以查看该 SIEM 应用程序的所有异常事件。我们提供若干可让您入门的常规检测作业。如果您希望添加自己的定制作业,只需从用于纳入定制作业的 {machineLearning} 应用程序中创建定制作业并使用“SIEM”标记它们。", - "xpack.siem.components.mlPopup.anomalyDetectionTitle": "异常检测设置", "xpack.siem.components.mlPopup.cloudLink": "云部署", "xpack.siem.components.mlPopup.errors.createJobFailureTitle": "创建作业失败", "xpack.siem.components.mlPopup.errors.startJobFailureTitle": "启动作业失败", From ee02df445ba64dc99a274d7a9bad9b773552e1e3 Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Mon, 6 Apr 2020 15:45:11 -0400 Subject: [PATCH 4/8] [EPM] fix /packages response to return older packages (#62623) * compare package list by name * use the internal property, adding as saved object attribute * remove HiddenPackages type --- .../plugins/ingest_manager/server/saved_objects.ts | 1 + .../server/services/epm/packages/get.ts | 12 ++++++------ .../server/services/epm/packages/install.ts | 8 +++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/saved_objects.ts b/x-pack/plugins/ingest_manager/server/saved_objects.ts index 13f84e4efa790..6800cb4056700 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects.ts @@ -148,6 +148,7 @@ export const savedObjectMappings = { properties: { name: { type: 'keyword' }, version: { type: 'keyword' }, + internal: { type: 'boolean' }, installed: { type: 'nested', properties: { diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts index d655b81f8cdef..e963ea138dfd5 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts @@ -31,17 +31,17 @@ export async function getPackages( Object.assign({}, item, { title: item.title || nameAsTitle(item.name) }) ); }); - const searchObjects = registryItems.map(({ name, version }) => ({ + // get the installed packages + const results = await savedObjectsClient.find({ type: PACKAGES_SAVED_OBJECT_TYPE, - id: `${name}-${version}`, - })); - const results = await savedObjectsClient.bulkGet(searchObjects); - const savedObjects = results.saved_objects.filter(o => !o.error); // ignore errors for now + }); + // filter out any internal packages + const savedObjectsVisible = results.saved_objects.filter(o => !o.attributes.internal); const packageList = registryItems .map(item => createInstallableFrom( item, - savedObjects.find(({ id }) => id === `${item.name}-${item.version}`) + savedObjectsVisible.find(({ attributes }) => attributes.name === item.name) ) ) .sort(sortByName); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts index 3cce238f582f4..82523e37509d1 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts @@ -87,7 +87,7 @@ export async function installPackage(options: { }): Promise { const { savedObjectsClient, pkgkey, callCluster } = options; const registryPackageInfo = await Registry.fetchInfo(pkgkey); - const { name: pkgName, version: pkgVersion } = registryPackageInfo; + const { name: pkgName, version: pkgVersion, internal = false } = registryPackageInfo; const installKibanaAssetsPromise = installKibanaAssets({ savedObjectsClient, @@ -116,6 +116,7 @@ export async function installPackage(options: { pkgkey, pkgName, pkgVersion, + internal, toSave, }); return toSave; @@ -145,9 +146,10 @@ export async function saveInstallationReferences(options: { pkgkey: string; pkgName: string; pkgVersion: string; + internal: boolean; toSave: AssetReference[]; }) { - const { savedObjectsClient, pkgkey, pkgName, pkgVersion, toSave } = options; + const { savedObjectsClient, pkgkey, pkgName, pkgVersion, internal, toSave } = options; const installation = await getInstallation({ savedObjectsClient, pkgkey }); const savedRefs = installation?.installed || []; const mergeRefsReducer = (current: AssetReference[], pending: AssetReference) => { @@ -159,7 +161,7 @@ export async function saveInstallationReferences(options: { const toInstall = toSave.reduce(mergeRefsReducer, savedRefs); await savedObjectsClient.create( PACKAGES_SAVED_OBJECT_TYPE, - { installed: toInstall, name: pkgName, version: pkgVersion }, + { installed: toInstall, name: pkgName, version: pkgVersion, internal }, { id: pkgkey, overwrite: true } ); From a7b3e5539efa7cc26458770f585b52e219cf4052 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Mon, 6 Apr 2020 21:47:15 +0200 Subject: [PATCH 5/8] [ML] Fix boolean cell values in analytics table result views and transforms wizard. (#62618) Fixes the rendering of boolean values in table results views and transforms wizards: - Fixed: Boolean cells in the transform wizard ended up being empty. - Fixed: Boolean cells in regression/classification result table would render as Yes/No instead of true/false. --- .../classification_exploration/results_table.tsx | 1 + .../components/regression_exploration/results_table.tsx | 1 + .../public/app/components/pivot_preview/pivot_preview.tsx | 4 ++++ .../source_index_preview/source_index_preview.tsx | 7 +++++++ 4 files changed, 13 insertions(+) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx index fbdb47c87c7ef..9758dd969b443 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/results_table.tsx @@ -211,6 +211,7 @@ export const ResultsTable: FC = React.memo( switch (type) { case ES_FIELD_TYPES.BOOLEAN: column.dataType = ES_FIELD_TYPES.BOOLEAN; + column.render = d => (d ? 'true' : 'false'); break; case ES_FIELD_TYPES.DATE: column.align = 'right'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx index 8d53a9278a1af..a35be5400f46b 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/results_table.tsx @@ -213,6 +213,7 @@ export const ResultsTable: FC = React.memo( switch (type) { case ES_FIELD_TYPES.BOOLEAN: column.dataType = ES_FIELD_TYPES.BOOLEAN; + column.render = d => (d ? 'true' : 'false'); break; case ES_FIELD_TYPES.DATE: column.align = 'right'; diff --git a/x-pack/plugins/transform/public/app/components/pivot_preview/pivot_preview.tsx b/x-pack/plugins/transform/public/app/components/pivot_preview/pivot_preview.tsx index c0c85f74418fc..c50df0366d698 100644 --- a/x-pack/plugins/transform/public/app/components/pivot_preview/pivot_preview.tsx +++ b/x-pack/plugins/transform/public/app/components/pivot_preview/pivot_preview.tsx @@ -245,6 +245,10 @@ export const PivotPreview: FC = React.memo( return formatHumanReadableDateTimeSeconds(moment(cellValue).unix() * 1000); } + if (previewMappings.properties[columnId].type === ES_FIELD_TYPES.BOOLEAN) { + return cellValue ? 'true' : 'false'; + } + return cellValue; }; }, [pageData, pagination.pageIndex, pagination.pageSize, previewMappings.properties]); diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/source_index_preview/source_index_preview.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/source_index_preview/source_index_preview.tsx index c56263b721032..bcdeb7ddb0d36 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/source_index_preview/source_index_preview.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/source_index_preview/source_index_preview.tsx @@ -105,6 +105,9 @@ export const SourceIndexPreview: React.FC = React.memo(({ indexPattern, q let schema; switch (field?.type) { + case KBN_FIELD_TYPES.BOOLEAN: + schema = 'boolean'; + break; case KBN_FIELD_TYPES.DATE: schema = 'datetime'; break; @@ -190,6 +193,10 @@ export const SourceIndexPreview: React.FC = React.memo(({ indexPattern, q return formatHumanReadableDateTimeSeconds(moment(cellValue).unix() * 1000); } + if (field?.type === KBN_FIELD_TYPES.BOOLEAN) { + return cellValue ? 'true' : 'false'; + } + return cellValue; }; }, [data, indexPattern.fields, pagination.pageIndex, pagination.pageSize]); From f80925af9768cd5e9b4ccd3d4d4d5ebd739fe49c Mon Sep 17 00:00:00 2001 From: Aaron Caldwell Date: Mon, 6 Apr 2020 14:01:38 -0600 Subject: [PATCH 6/8] [Maps] Move layers to np maps (#61877) * Move layers to new location * Update layer path refs * Update np kibana services to cover all required services * Init np kibana services in legacy plugin. Port init functions to np * Path updates, supporting file moves, general clean up * More moves of related files and clean-up of legacy refs * Path updates. Typescript warning fixes * Update test paths * Clean up unused kibana services usage in legacy * Remove unused http ref * Test fixes and clean up * Remove unused snapshots * Add np service init to embeddables too * Move validate color picker to NP --- .../maps/public/actions/map_actions.d.ts | 57 +------------ .../maps/public/angular/get_initial_layers.js | 9 +- .../public/angular/get_initial_layers.test.js | 8 +- .../public/angular/services/saved_gis_map.js | 3 +- .../connected_components/gis_map/index.d.ts | 3 +- .../connected_components/gis_map/view.js | 3 +- .../layer_addpanel/import_editor/view.js | 3 +- .../source_select/source_select.js | 3 +- .../join_editor/resources/join_expression.js | 6 +- .../resources/metrics_expression.js | 3 +- .../resources/metrics_expression.test.js | 2 +- .../layer_settings/layer_settings.js | 3 +- .../layer_panel/view.d.ts | 8 +- .../feature_geometry_filter_form.js | 3 +- .../map/mb/draw_control/draw_control.js | 3 +- .../connected_components/map/mb/utils.js | 63 ++------------ .../connected_components/map/mb/view.js | 9 +- .../maps/public/embeddable/map_embeddable.tsx | 3 +- .../embeddable/map_embeddable_factory.ts | 7 ++ x-pack/legacy/plugins/maps/public/index.scss | 2 +- x-pack/legacy/plugins/maps/public/index.ts | 6 +- .../plugins/maps/public/kibana_services.js | 62 -------------- .../plugins/maps/public/layers/_index.scss | 1 - .../maps/public/layers/styles/_index.scss | 4 - x-pack/legacy/plugins/maps/public/plugin.ts | 36 ++++---- .../maps/public/selectors/map_selectors.js | 21 +++-- .../public/selectors/map_selectors.test.js | 10 +-- .../maps/public/actions/map_actions.d.ts | 64 +++++++++++++++ .../add_tooltip_field_popover.test.js.snap | 0 .../tooltip_selector.test.js.snap | 0 .../validated_range.test.js.snap | 0 .../components/add_tooltip_field_popover.js | 2 +- .../add_tooltip_field_popover.test.js | 0 .../maps/public/components/metric_editor.js | 0 .../maps/public/components/metric_select.js | 0 .../maps/public/components/metrics_editor.js | 0 .../components/no_index_pattern_callout.js | 8 +- .../public/components/single_field_select.js | 2 +- .../public/components/tooltip_selector.js | 0 .../components/tooltip_selector.test.js | 0 .../maps/public/components/validated_range.js | 0 .../public/components/validated_range.test.js | 0 .../layer_panel/view.d.ts | 14 ++++ .../map/mb/image_utils.js | 0 .../connected_components/map/mb/utils.js | 62 ++++++++++++++ .../maps/public/elasticsearch_geo_utils.js | 0 .../public/elasticsearch_geo_utils.test.js | 2 +- .../plugins/maps/public/index_pattern_util.js | 2 +- .../maps/public/index_pattern_util.test.js | 0 x-pack/plugins/maps/public/kibana_services.js | 82 +++++++++++++++++++ x-pack/plugins/maps/public/layers/_index.scss | 1 + .../public/layers/blended_vector_layer.ts | 0 .../public/layers/fields/ems_file_field.ts | 0 .../public/layers/fields/es_agg_field.test.ts | 0 .../maps/public/layers/fields/es_agg_field.ts | 0 .../maps/public/layers/fields/es_doc_field.ts | 4 +- .../maps/public/layers/fields/field.ts | 0 .../layers/fields/kibana_region_field.ts | 0 .../fields/top_term_percentage_field.ts | 0 .../maps/public/layers/heatmap_layer.js | 0 .../maps/public/layers/joins/inner_join.js | 0 .../public/layers/joins/inner_join.test.js | 0 .../plugins/maps/public/layers/joins/join.ts | 0 .../plugins/maps/public/layers/layer.d.ts | 0 .../plugins/maps/public/layers/layer.js | 2 +- .../public/layers/layer_wizard_registry.ts | 0 .../maps/public/layers/load_layer_wizards.js | 0 .../create_client_file_source_editor.js | 0 .../client_file_source/geojson_file_source.js | 0 .../sources/client_file_source/index.js | 0 .../ems_file_source/create_source_editor.js | 0 .../ems_file_source/ems_file_source.d.ts | 0 .../ems_file_source/ems_file_source.js | 0 .../ems_file_source/ems_file_source.test.js | 0 .../layers/sources/ems_file_source/index.js | 0 .../ems_file_source/update_source_editor.js | 0 .../sources/ems_tms_source/ems_tms_source.js | 0 .../ems_tms_source/ems_tms_source.test.js | 0 .../layers/sources/ems_tms_source/index.js | 0 .../ems_tms_source/tile_service_select.js | 0 .../ems_tms_source/update_source_editor.js | 0 .../layers/sources/ems_unavailable_message.js | 0 .../public/layers/sources/es_agg_source.d.ts | 0 .../public/layers/sources/es_agg_source.js | 0 .../layers/sources/es_agg_source.test.ts | 0 .../es_geo_grid_source/convert_to_geojson.js | 0 .../convert_to_geojson.test.ts | 0 .../create_source_editor.js | 0 .../es_geo_grid_source.d.ts | 0 .../es_geo_grid_source/es_geo_grid_source.js | 0 .../es_geo_grid_source.test.ts | 0 .../es_geo_grid_source/geo_tile_utils.js | 0 .../es_geo_grid_source/geo_tile_utils.test.js | 0 .../sources/es_geo_grid_source/index.js | 0 .../es_geo_grid_source/render_as_select.tsx | 0 .../es_geo_grid_source/resolution_editor.js | 0 .../update_source_editor.js | 2 +- .../es_pew_pew_source/convert_to_lines.js | 0 .../convert_to_lines.test.ts | 0 .../es_pew_pew_source/create_source_editor.js | 0 .../es_pew_pew_source/es_pew_pew_source.js | 2 +- .../es_pew_pew_source/update_source_editor.js | 2 +- .../__snapshots__/scaling_form.test.tsx.snap | 0 .../update_source_editor.test.js.snap | 0 .../sources/es_search_source/constants.js | 0 .../es_search_source/create_source_editor.js | 2 +- .../es_search_source/es_search_source.d.ts | 0 .../es_search_source/es_search_source.js | 0 .../es_search_source/es_search_source.test.ts | 0 .../layers/sources/es_search_source/index.js | 0 .../es_search_source/load_index_settings.js | 0 .../es_search_source/scaling_form.test.tsx | 0 .../sources/es_search_source/scaling_form.tsx | 4 +- .../es_search_source/update_source_editor.js | 2 +- .../update_source_editor.test.js | 0 .../maps/public/layers/sources/es_source.d.ts | 2 +- .../maps/public/layers/sources/es_source.js | 2 +- .../public/layers/sources/es_term_source.d.ts | 0 .../public/layers/sources/es_term_source.js | 0 .../layers/sources/es_term_source.test.js | 0 .../create_source_editor.js | 0 .../sources/kibana_regionmap_source/index.js | 0 .../kibana_regionmap_source.d.ts | 0 .../kibana_regionmap_source.js | 0 .../create_source_editor.js | 0 .../sources/kibana_tilemap_source/index.js | 0 .../kibana_tilemap_source.js | 0 .../maps/public/layers/sources/source.d.ts | 0 .../maps/public/layers/sources/source.js | 2 +- .../public/layers/sources/source_registry.ts | 0 .../public/layers/sources/tms_source.d.ts | 0 .../maps/public/layers/sources/tms_source.js | 0 .../layers/sources/vector_feature_types.js | 0 .../public/layers/sources/vector_source.d.ts | 0 .../public/layers/sources/vector_source.js | 0 .../public/layers/sources/wms_source/index.js | 0 .../layers/sources/wms_source/wms_client.js | 0 .../sources/wms_source/wms_client.test.js | 0 .../wms_source/wms_create_source_editor.js | 0 .../layers/sources/wms_source/wms_source.js | 0 .../public/layers/sources/xyz_tms_source.d.ts | 0 .../public/layers/sources/xyz_tms_source.js | 0 .../layers/sources/xyz_tms_source.test.ts | 0 .../maps/public/layers/styles/_index.scss | 4 + .../public/layers/styles/abstract_style.js | 0 .../maps/public/layers/styles/color_utils.js | 2 +- .../public/layers/styles/color_utils.test.js | 0 .../styles/components/_color_gradient.scss | 0 .../styles/components/color_gradient.js | 0 .../components/ranged_style_legend_row.js | 0 .../heatmap_style_editor.test.js.snap | 0 .../heatmap/components/heatmap_constants.js | 0 .../components/heatmap_style_editor.js | 0 .../components/heatmap_style_editor.test.js | 0 .../components/legend/heatmap_legend.js | 0 .../layers/styles/heatmap/heatmap_style.js | 0 .../vector/components/_style_prop_editor.scss | 0 .../vector/components/color/_color_stops.scss | 0 .../components/color/color_map_select.js | 0 .../vector/components/color/color_stops.js | 0 .../color/color_stops_categorical.js | 0 .../components/color/color_stops_ordinal.js | 0 .../components/color/color_stops_utils.js | 0 .../components/color/dynamic_color_form.js | 0 .../color/mb_validated_color_picker.tsx | 0 .../components/color/static_color_form.js | 0 .../color/vector_style_color_editor.js | 0 .../categorical_field_meta_popover.tsx | 0 .../field_meta/field_meta_popover.tsx | 0 .../field_meta/ordinal_field_meta_popover.tsx | 0 .../styles/vector/components/field_select.js | 2 +- .../components/get_vector_style_label.js | 0 .../components/label/dynamic_label_form.js | 0 .../components/label/static_label_form.js | 0 .../vector_style_label_border_size_editor.js | 0 .../label/vector_style_label_editor.js | 0 .../__snapshots__/vector_icon.test.js.snap | 0 .../vector/components/legend/category.js | 0 .../vector/components/legend/circle_icon.js | 0 .../extract_color_from_style_property.js | 0 .../vector/components/legend/line_icon.js | 0 .../vector/components/legend/polygon_icon.js | 0 .../vector/components/legend/symbol_icon.js | 0 .../vector/components/legend/vector_icon.js | 0 .../components/legend/vector_icon.test.js | 0 .../components/legend/vector_style_legend.js | 0 .../orientation/dynamic_orientation_form.js | 0 .../orientation/orientation_editor.js | 0 .../orientation/static_orientation_form.js | 0 .../components/size/dynamic_size_form.js | 0 .../components/size/size_range_selector.js | 2 +- .../components/size/static_size_form.js | 0 .../size/vector_style_size_editor.js | 0 .../styles/vector/components/stop_input.js | 0 .../vector/components/style_map_select.js | 0 .../vector/components/style_option_shapes.js | 0 .../vector/components/style_prop_editor.js | 0 .../__snapshots__/icon_select.test.js.snap | 0 .../components/symbol/_icon_select.scss | 0 .../components/symbol/dynamic_icon_form.js | 0 .../components/symbol/icon_map_select.js | 0 .../vector/components/symbol/icon_select.js | 0 .../components/symbol/icon_select.test.js | 0 .../vector/components/symbol/icon_stops.js | 0 .../components/symbol/icon_stops.test.js | 0 .../components/symbol/static_icon_form.js | 0 .../symbol/vector_style_icon_editor.js | 0 .../vector_style_symbolize_as_editor.js | 0 .../vector/components/vector_style_editor.js | 0 .../dynamic_color_property.test.js.snap | 0 .../components/categorical_legend.js | 0 .../properties/components/ordinal_legend.js | 0 .../properties/dynamic_color_property.js | 0 .../properties/dynamic_color_property.test.js | 0 .../properties/dynamic_icon_property.js | 0 .../dynamic_orientation_property.js | 0 .../properties/dynamic_size_property.js | 0 .../properties/dynamic_style_property.d.ts | 0 .../properties/dynamic_style_property.js | 0 .../properties/dynamic_text_property.js | 0 .../properties/label_border_size_property.js | 0 .../properties/static_color_property.js | 0 .../vector/properties/static_icon_property.js | 0 .../properties/static_orientation_property.js | 0 .../vector/properties/static_size_property.js | 0 .../properties/static_style_property.js | 0 .../vector/properties/static_text_property.js | 0 .../vector/properties/style_property.ts | 0 .../properties/symbolize_as_property.js | 0 .../public/layers/styles/vector/style_meta.ts | 0 .../public/layers/styles/vector/style_util.js | 0 .../layers/styles/vector/style_util.test.js | 0 .../layers/styles/vector/symbol_utils.js | 0 .../layers/styles/vector/symbol_utils.test.js | 0 .../layers/styles/vector/vector_style.d.ts | 0 .../layers/styles/vector/vector_style.js | 0 .../layers/styles/vector/vector_style.test.js | 0 .../styles/vector/vector_style_defaults.ts | 0 .../maps/public/layers/tile_layer.d.ts | 0 .../plugins/maps/public/layers/tile_layer.js | 0 .../maps/public/layers/tile_layer.test.ts | 0 .../tooltips/es_agg_tooltip_property.ts | 0 .../layers/tooltips/es_tooltip_property.ts | 4 +- .../layers/tooltips/join_tooltip_property.ts | 2 +- .../layers/tooltips/tooltip_property.ts | 4 +- .../layers/util/assign_feature_ids.test.ts | 0 .../public/layers/util/assign_feature_ids.ts | 0 .../public/layers/util/can_skip_fetch.test.js | 0 .../maps/public/layers/util/can_skip_fetch.ts | 0 .../maps/public/layers/util/data_request.ts | 0 .../public/layers/util/es_agg_utils.test.ts | 0 .../maps/public/layers/util/es_agg_utils.ts | 2 +- .../public/layers/util/is_metric_countable.ts | 0 .../layers/util/is_refresh_only_query.ts | 0 .../layers/util/mb_filter_expressions.ts | 0 .../maps/public/layers/vector_layer.d.ts | 0 .../maps/public/layers/vector_layer.js | 0 .../maps/public/layers/vector_tile_layer.js | 0 .../{legacy => }/plugins/maps/public/meta.js | 25 +++--- .../plugins/maps/public/meta.test.js | 45 ++++------ x-pack/plugins/maps/public/plugin.ts | 37 +++++++++ 261 files changed, 417 insertions(+), 318 deletions(-) delete mode 100644 x-pack/legacy/plugins/maps/public/layers/_index.scss delete mode 100644 x-pack/legacy/plugins/maps/public/layers/styles/_index.scss create mode 100644 x-pack/plugins/maps/public/actions/map_actions.d.ts rename x-pack/{legacy => }/plugins/maps/public/components/__snapshots__/add_tooltip_field_popover.test.js.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/components/__snapshots__/tooltip_selector.test.js.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/components/__snapshots__/validated_range.test.js.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/components/add_tooltip_field_popover.js (98%) rename x-pack/{legacy => }/plugins/maps/public/components/add_tooltip_field_popover.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/components/metric_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/components/metric_select.js (100%) rename x-pack/{legacy => }/plugins/maps/public/components/metrics_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/components/no_index_pattern_callout.js (85%) rename x-pack/{legacy => }/plugins/maps/public/components/single_field_select.js (95%) rename x-pack/{legacy => }/plugins/maps/public/components/tooltip_selector.js (100%) rename x-pack/{legacy => }/plugins/maps/public/components/tooltip_selector.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/components/validated_range.js (100%) rename x-pack/{legacy => }/plugins/maps/public/components/validated_range.test.js (100%) create mode 100644 x-pack/plugins/maps/public/connected_components/layer_panel/view.d.ts rename x-pack/{legacy => }/plugins/maps/public/connected_components/map/mb/image_utils.js (100%) create mode 100644 x-pack/plugins/maps/public/connected_components/map/mb/utils.js rename x-pack/{legacy => }/plugins/maps/public/elasticsearch_geo_utils.js (100%) rename x-pack/{legacy => }/plugins/maps/public/elasticsearch_geo_utils.test.js (99%) rename x-pack/{legacy => }/plugins/maps/public/index_pattern_util.js (95%) rename x-pack/{legacy => }/plugins/maps/public/index_pattern_util.test.js (100%) create mode 100644 x-pack/plugins/maps/public/layers/_index.scss rename x-pack/{legacy => }/plugins/maps/public/layers/blended_vector_layer.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/fields/ems_file_field.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/fields/es_agg_field.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/fields/es_agg_field.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/fields/es_doc_field.ts (96%) rename x-pack/{legacy => }/plugins/maps/public/layers/fields/field.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/fields/kibana_region_field.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/fields/top_term_percentage_field.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/heatmap_layer.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/joins/inner_join.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/joins/inner_join.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/joins/join.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/layer.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/layer.js (99%) rename x-pack/{legacy => }/plugins/maps/public/layers/layer_wizard_registry.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/load_layer_wizards.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/client_file_source/create_client_file_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/client_file_source/index.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_file_source/create_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_file_source/index.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_file_source/update_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_tms_source/index.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_tms_source/tile_service_select.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_tms_source/update_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/ems_unavailable_message.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_agg_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_agg_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_agg_source.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/index.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/render_as_select.tsx (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/resolution_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js (97%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_pew_pew_source/create_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js (98%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js (96%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/constants.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js (98%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/es_search_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/es_search_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/es_search_source.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/index.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/load_index_settings.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/scaling_form.test.tsx (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/scaling_form.tsx (97%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js (98%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_search_source/update_source_editor.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_source.d.ts (92%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_source.js (99%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_term_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_term_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/es_term_source.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/kibana_regionmap_source/create_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/kibana_regionmap_source/index.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/kibana_tilemap_source/create_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/kibana_tilemap_source/index.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/source.js (96%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/source_registry.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/tms_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/tms_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/vector_feature_types.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/vector_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/vector_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/wms_source/index.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/wms_source/wms_client.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/wms_source/wms_client.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/wms_source/wms_create_source_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/wms_source/wms_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/xyz_tms_source.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/xyz_tms_source.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/sources/xyz_tms_source.test.ts (100%) create mode 100644 x-pack/plugins/maps/public/layers/styles/_index.scss rename x-pack/{legacy => }/plugins/maps/public/layers/styles/abstract_style.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/color_utils.js (98%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/color_utils.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/components/_color_gradient.scss (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/components/color_gradient.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/components/ranged_style_legend_row.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/heatmap/components/__snapshots__/heatmap_style_editor.test.js.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/heatmap/components/heatmap_constants.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/heatmap/components/legend/heatmap_legend.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/heatmap/heatmap_style.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/_style_prop_editor.scss (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/_color_stops.scss (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/color_stops.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/color_stops_utils.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/mb_validated_color_picker.tsx (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/color/vector_style_color_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/field_meta/categorical_field_meta_popover.tsx (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/field_meta/field_meta_popover.tsx (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/field_meta/ordinal_field_meta_popover.tsx (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/field_select.js (97%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/get_vector_style_label.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/label/dynamic_label_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/label/static_label_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_border_size_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/__snapshots__/vector_icon.test.js.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/category.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/circle_icon.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/extract_color_from_style_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/line_icon.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/polygon_icon.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/symbol_icon.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/legend/vector_style_legend.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/orientation/dynamic_orientation_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/orientation/orientation_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/orientation/static_orientation_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/size/dynamic_size_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js (92%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/size/static_size_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/size/vector_style_size_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/stop_input.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/style_map_select.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/style_option_shapes.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/__snapshots__/icon_select.test.js.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/_icon_select.scss (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/dynamic_icon_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/static_icon_form.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_icon_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_symbolize_as_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/components/vector_style_editor.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/__snapshots__/dynamic_color_property.test.js.snap (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/components/categorical_legend.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/components/ordinal_legend.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/dynamic_icon_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/label_border_size_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/static_color_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/static_icon_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/static_orientation_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/static_size_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/static_style_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/static_text_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/style_property.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/properties/symbolize_as_property.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/style_meta.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/style_util.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/style_util.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/symbol_utils.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/symbol_utils.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/vector_style.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/vector_style.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/vector_style.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/styles/vector/vector_style_defaults.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/tile_layer.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/tile_layer.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/tile_layer.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/tooltips/es_tooltip_property.ts (95%) rename x-pack/{legacy => }/plugins/maps/public/layers/tooltips/join_tooltip_property.ts (96%) rename x-pack/{legacy => }/plugins/maps/public/layers/tooltips/tooltip_property.ts (92%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/assign_feature_ids.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/assign_feature_ids.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/can_skip_fetch.test.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/can_skip_fetch.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/data_request.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/es_agg_utils.test.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/es_agg_utils.ts (95%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/is_metric_countable.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/is_refresh_only_query.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/util/mb_filter_expressions.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/vector_layer.d.ts (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/vector_layer.js (100%) rename x-pack/{legacy => }/plugins/maps/public/layers/vector_tile_layer.js (100%) rename x-pack/{legacy => }/plugins/maps/public/meta.js (76%) rename x-pack/{legacy => }/plugins/maps/public/meta.test.js (57%) diff --git a/x-pack/legacy/plugins/maps/public/actions/map_actions.d.ts b/x-pack/legacy/plugins/maps/public/actions/map_actions.d.ts index b4a8ff90c3512..34f8c30b51874 100644 --- a/x-pack/legacy/plugins/maps/public/actions/map_actions.d.ts +++ b/x-pack/legacy/plugins/maps/public/actions/map_actions.d.ts @@ -5,59 +5,4 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import { Filter, Query, TimeRange } from 'src/plugins/data/public'; -import { AnyAction } from 'redux'; -import { LAYER_TYPE } from '../../common/constants'; -import { DataMeta, MapFilters } from '../../common/descriptor_types'; -import { - MapCenterAndZoom, - MapRefreshConfig, -} from '../../../../../plugins/maps/common/descriptor_types'; - -export type SyncContext = { - startLoading(dataId: string, requestToken: symbol, meta: DataMeta): void; - stopLoading(dataId: string, requestToken: symbol, data: unknown, meta: DataMeta): void; - onLoadError(dataId: string, requestToken: symbol, errorMessage: string): void; - updateSourceData(newData: unknown): void; - isRequestStillActive(dataId: string, requestToken: symbol): boolean; - registerCancelCallback(requestToken: symbol, callback: () => void): void; - dataFilters: MapFilters; -}; - -export function updateSourceProp( - layerId: string, - propName: string, - value: unknown, - newLayerType?: LAYER_TYPE -): void; - -export function setGotoWithCenter(config: MapCenterAndZoom): AnyAction; - -export function replaceLayerList(layerList: unknown[]): AnyAction; - -export type QueryGroup = { - filters: Filter[]; - query?: Query; - timeFilters?: TimeRange; - refresh?: boolean; -}; - -export function setQuery(query: QueryGroup): AnyAction; - -export function setRefreshConfig(config: MapRefreshConfig): AnyAction; - -export function disableScrollZoom(): AnyAction; - -export function disableInteractive(): AnyAction; - -export function disableTooltipControl(): AnyAction; - -export function hideToolbarOverlay(): AnyAction; - -export function hideLayerControl(): AnyAction; - -export function hideViewControl(): AnyAction; - -export function setHiddenLayers(hiddenLayerIds: string[]): AnyAction; - -export function addLayerWithoutDataSync(layerDescriptor: unknown): AnyAction; +export * from '../../../../../plugins/maps/public/actions/map_actions'; diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.js b/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.js index 8fc32aef54770..5e497ff0736b2 100644 --- a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.js +++ b/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.js @@ -4,10 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ import _ from 'lodash'; -import { KibanaTilemapSource } from '../layers/sources/kibana_tilemap_source'; -import { EMSTMSSource } from '../layers/sources/ems_tms_source'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { KibanaTilemapSource } from '../../../../../plugins/maps/public/layers/sources/kibana_tilemap_source'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { EMSTMSSource } from '../../../../../plugins/maps/public/layers/sources/ems_tms_source'; import { getInjectedVarFunc } from '../kibana_services'; -import { getKibanaTileMap } from '../meta'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getKibanaTileMap } from '../../../../../plugins/maps/public/meta'; export function getInitialLayers(layerListJSON, initialLayers = []) { if (layerListJSON) { diff --git a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js b/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js index f41ed26b2a05d..5334beaaf714a 100644 --- a/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js +++ b/x-pack/legacy/plugins/maps/public/angular/get_initial_layers.test.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -jest.mock('../meta', () => { +jest.mock('../../../../../plugins/maps/public/meta', () => { return {}; }); jest.mock('../kibana_services'); @@ -32,7 +32,7 @@ describe('Saved object has layer list', () => { describe('kibana.yml configured with map.tilemap.url', () => { beforeAll(() => { - require('../meta').getKibanaTileMap = () => { + require('../../../../../plugins/maps/public/meta').getKibanaTileMap = () => { return { url: 'myTileUrl', }; @@ -62,7 +62,7 @@ describe('kibana.yml configured with map.tilemap.url', () => { describe('EMS is enabled', () => { beforeAll(() => { - require('../meta').getKibanaTileMap = () => { + require('../../../../../plugins/maps/public/meta').getKibanaTileMap = () => { return null; }; require('../kibana_services').getInjectedVarFunc = () => key => { @@ -106,7 +106,7 @@ describe('EMS is enabled', () => { describe('EMS is not enabled', () => { beforeAll(() => { - require('../meta').getKibanaTileMap = () => { + require('../../../../../plugins/maps/public/meta').getKibanaTileMap = () => { return null; }; diff --git a/x-pack/legacy/plugins/maps/public/angular/services/saved_gis_map.js b/x-pack/legacy/plugins/maps/public/angular/services/saved_gis_map.js index f846d3d4a617f..990a0613da681 100644 --- a/x-pack/legacy/plugins/maps/public/angular/services/saved_gis_map.js +++ b/x-pack/legacy/plugins/maps/public/angular/services/saved_gis_map.js @@ -17,7 +17,8 @@ import { getFilters, } from '../../selectors/map_selectors'; import { getIsLayerTOCOpen, getOpenTOCDetails } from '../../selectors/ui_selectors'; -import { convertMapExtentToPolygon } from '../../elasticsearch_geo_utils'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { convertMapExtentToPolygon } from '../../../../../../plugins/maps/public/elasticsearch_geo_utils'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { copyPersistentState } from '../../../../../../plugins/maps/public/reducers/util'; import { extractReferences, injectReferences } from '../../../common/migrations/references'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.d.ts b/x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.d.ts index 00a9400109dc1..8689d88297171 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.d.ts +++ b/x-pack/legacy/plugins/maps/public/connected_components/gis_map/index.d.ts @@ -6,7 +6,8 @@ import React from 'react'; import { Filter } from 'src/plugins/data/public'; -import { RenderToolTipContent } from '../../layers/tooltips/tooltip_property'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { RenderToolTipContent } from '../../../../../../plugins/maps/public/layers/tooltips/tooltip_property'; export const GisMap: React.ComponentType<{ addFilters: ((filters: Filter[]) => void) | null; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/view.js b/x-pack/legacy/plugins/maps/public/connected_components/gis_map/view.js index 97139103ab7c1..358313b8f5b6d 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/gis_map/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/gis_map/view.js @@ -13,7 +13,8 @@ import { LayerPanel } from '../layer_panel/index'; import { AddLayerPanel } from '../layer_addpanel/index'; import { EuiFlexGroup, EuiFlexItem, EuiCallOut } from '@elastic/eui'; import { ExitFullScreenButton } from 'ui/exit_full_screen'; -import { getIndexPatternsFromIds } from '../../index_pattern_util'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getIndexPatternsFromIds } from '../../../../../../plugins/maps/public/index_pattern_util'; import { ES_GEO_FIELD_TYPE } from '../../../common/constants'; import { indexPatterns as indexPatternsUtils } from '../../../../../../../src/plugins/data/public'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js index 762409b256286..cb20d80733c33 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/import_editor/view.js @@ -7,7 +7,8 @@ import React, { Fragment } from 'react'; import { EuiSpacer, EuiPanel, EuiButtonEmpty } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { uploadLayerWizardConfig } from '../../../layers/sources/client_file_source'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { uploadLayerWizardConfig } from '../../../../../../../plugins/maps/public/layers/sources/client_file_source'; export const ImportEditor = ({ clearSource, isIndexingTriggered, ...props }) => { const editorProperties = getEditorProperties({ isIndexingTriggered, ...props }); diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js index b34a432bec88c..67cc17ebaa224 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/source_select/source_select.js @@ -5,7 +5,8 @@ */ import React, { Fragment } from 'react'; -import { getLayerWizards } from '../../../layers/layer_wizard_registry'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getLayerWizards } from '../../../../../../../plugins/maps/public/layers/layer_wizard_registry'; import { EuiTitle, EuiSpacer, EuiCard, EuiIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import _ from 'lodash'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js index f7edcf6e85e25..6c080ace4442a 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/join_expression.js @@ -16,9 +16,11 @@ import { EuiFormHelpText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { SingleFieldSelect } from '../../../../components/single_field_select'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { SingleFieldSelect } from '../../../../../../../../plugins/maps/public/components/single_field_select'; import { FormattedMessage } from '@kbn/i18n/react'; -import { getTermsFields } from '../../../../index_pattern_util'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getTermsFields } from '../../../../../../../../plugins/maps/public/index_pattern_util'; import { getIndexPatternService, getIndexPatternSelectComponent, diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js index 0944d0e602c2f..c6a79a398f9af 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.js @@ -14,7 +14,8 @@ import { EuiFormErrorText, EuiFormHelpText, } from '@elastic/eui'; -import { MetricsEditor } from '../../../../components/metrics_editor'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { MetricsEditor } from '../../../../../../../../plugins/maps/public/components/metrics_editor'; import { FormattedMessage } from '@kbn/i18n/react'; import { AGG_TYPE } from '../../../../../common/constants'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js index e4e3776c8e92c..d8bf862249448 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -jest.mock('../../../../components/metrics_editor', () => ({ +jest.mock('../../../../../../../../plugins/maps/public/components/metric_editor', () => ({ MetricsEditor: () => { return
mockMetricsEditor
; }, diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js index eb23607aa2150..bd27450943638 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js @@ -8,7 +8,8 @@ import React, { Fragment } from 'react'; import { EuiTitle, EuiPanel, EuiFormRow, EuiFieldText, EuiSpacer } from '@elastic/eui'; -import { ValidatedRange } from '../../../components/validated_range'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { ValidatedRange } from '../../../../../../../plugins/maps/public/components/validated_range'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ValidatedDualRange } from '../../../../../../../../src/plugins/kibana_react/public'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.d.ts b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.d.ts index 6d1d076c723ad..cf4fdc7be70c6 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.d.ts +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/view.d.ts @@ -5,10 +5,4 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import { LAYER_TYPE } from '../../../common/constants'; - -export type OnSourceChangeArgs = { - propName: string; - value: unknown; - newLayerType?: LAYER_TYPE; -}; +export * from '../../../../../../plugins/maps/public/connected_components/layer_panel/view'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js b/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js index 416af95581058..7063c50edad6a 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js @@ -8,7 +8,8 @@ import React, { Component, Fragment } from 'react'; import { EuiIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { createSpatialFilterWithGeometry } from '../../../elasticsearch_geo_utils'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { createSpatialFilterWithGeometry } from '../../../../../../../plugins/maps/public/elasticsearch_geo_utils'; import { GEO_JSON_TYPE } from '../../../../common/constants'; import { GeometryFilterForm } from '../../../components/geometry_filter_form'; import { UrlOverflowService } from 'ui/error_url_overflow'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js index 99abe5d108b5a..df2988d399c5b 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/draw_control/draw_control.js @@ -16,7 +16,8 @@ import { createSpatialFilterWithGeometry, getBoundingBoxGeometry, roundCoordinates, -} from '../../../../elasticsearch_geo_utils'; + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../../../../plugins/maps/public/elasticsearch_geo_utils'; import { DrawTooltip } from './draw_tooltip'; const mbDrawModes = MapboxDraw.modes; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js index a2850d2bb6c23..a1d1341b7c4f7 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js @@ -5,7 +5,13 @@ */ import _ from 'lodash'; -import { RGBAImage } from './image_utils'; +import { + loadSpriteSheetImageData, + addSpriteSheetToMapFromImageData, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../../../plugins/maps/public/connected_components/map/mb/utils'; + +export { loadSpriteSheetImageData, addSpriteSheetToMapFromImageData }; export function removeOrphanedSourcesAndLayers(mbMap, layerList) { const mbStyle = mbMap.getStyle(); @@ -95,62 +101,7 @@ export function syncLayerOrderForSingleLayer(mbMap, layerList) { }); } -function getImageData(img) { - const canvas = window.document.createElement('canvas'); - const context = canvas.getContext('2d'); - if (!context) { - throw new Error('failed to create canvas 2d context'); - } - canvas.width = img.width; - canvas.height = img.height; - context.drawImage(img, 0, 0, img.width, img.height); - return context.getImageData(0, 0, img.width, img.height); -} - -export async function loadSpriteSheetImageData(imgUrl) { - return new Promise((resolve, reject) => { - const image = new Image(); - if (isCrossOriginUrl(imgUrl)) { - image.crossOrigin = 'Anonymous'; - } - image.onload = el => { - const imgData = getImageData(el.currentTarget); - resolve(imgData); - }; - image.onerror = e => { - reject(e); - }; - image.src = imgUrl; - }); -} - -export function addSpriteSheetToMapFromImageData(json, imgData, mbMap) { - for (const imageId in json) { - if (!(json.hasOwnProperty(imageId) && !mbMap.hasImage(imageId))) { - continue; - } - const { width, height, x, y, sdf, pixelRatio } = json[imageId]; - if (typeof width !== 'number' || typeof height !== 'number') { - continue; - } - - const data = new RGBAImage({ width, height }); - RGBAImage.copy(imgData, data, { x, y }, { x: 0, y: 0 }, { width, height }); - mbMap.addImage(imageId, data, { pixelRatio, sdf }); - } -} - export async function addSpritesheetToMap(json, imgUrl, mbMap) { const imgData = await loadSpriteSheetImageData(imgUrl); addSpriteSheetToMapFromImageData(json, imgData, mbMap); } - -function isCrossOriginUrl(url) { - const a = window.document.createElement('a'); - a.href = url; - return ( - a.protocol !== window.document.location.protocol || - a.host !== window.document.location.host || - a.port !== window.document.location.port - ); -} diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js index 2995ea039e7a8..fedc1902d80a2 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js @@ -12,7 +12,8 @@ import { removeOrphanedSourcesAndLayers, addSpritesheetToMap, } from './utils'; -import { getGlyphUrl, isRetina } from '../../../meta'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getGlyphUrl, isRetina } from '../../../../../../../plugins/maps/public/meta'; import { DECIMAL_DEGREES_PRECISION, ZOOM_PRECISION } from '../../../../common/constants'; import mapboxgl from 'mapbox-gl/dist/mapbox-gl-csp'; import mbWorkerUrl from '!!file-loader!mapbox-gl/dist/mapbox-gl-csp-worker'; @@ -23,7 +24,11 @@ import sprites1 from '@elastic/maki/dist/sprite@1.png'; import sprites2 from '@elastic/maki/dist/sprite@2.png'; import { DrawControl } from './draw_control'; import { TooltipControl } from './tooltip_control'; -import { clampToLatBounds, clampToLonBounds } from '../../../elasticsearch_geo_utils'; +import { + clampToLatBounds, + clampToLonBounds, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../../../plugins/maps/public/elasticsearch_geo_utils'; mapboxgl.workerUrl = mbWorkerUrl; mapboxgl.setRTLTextPlugin(mbRtlPlugin); diff --git a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable.tsx b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable.tsx index 9544e8714f265..bdd2d863e6920 100644 --- a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable.tsx +++ b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable.tsx @@ -57,7 +57,8 @@ import { } from '../../../../../plugins/maps/public/reducers/non_serializable_instances'; import { getMapCenter, getMapZoom, getHiddenLayerIds } from '../selectors/map_selectors'; import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants'; -import { RenderToolTipContent } from '../layers/tooltips/tooltip_property'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { RenderToolTipContent } from '../../../../../plugins/maps/public/layers/tooltips/tooltip_property'; interface MapEmbeddableConfig { editUrl?: string; diff --git a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts index 5a036ed47fb62..5deb3057a449e 100644 --- a/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts +++ b/x-pack/legacy/plugins/maps/public/embeddable/map_embeddable_factory.ts @@ -27,6 +27,11 @@ import { getInitialLayers } from '../angular/get_initial_layers'; import { mergeInputWithSavedMap } from './merge_input_with_saved_map'; import '../angular/services/gis_map_saved_object_loader'; import { bindSetupCoreAndPlugins, bindStartCoreAndPlugins } from '../plugin'; +// @ts-ignore +import { + bindSetupCoreAndPlugins as bindNpSetupCoreAndPlugins, + bindStartCoreAndPlugins as bindNpStartCoreAndPlugins, +} from '../../../../../plugins/maps/public/plugin'; // eslint-disable-line @kbn/eslint/no-restricted-paths export class MapEmbeddableFactory implements EmbeddableFactoryDefinition { type = MAP_SAVED_OBJECT_TYPE; @@ -40,7 +45,9 @@ export class MapEmbeddableFactory implements EmbeddableFactoryDefinition { constructor() { // Init required services. Necessary while in legacy bindSetupCoreAndPlugins(npSetup.core, npSetup.plugins); + bindNpSetupCoreAndPlugins(npSetup.core, npSetup.plugins); bindStartCoreAndPlugins(npStart.core, npStart.plugins); + bindNpStartCoreAndPlugins(npStart.core, npStart.plugins); } async isEditable() { diff --git a/x-pack/legacy/plugins/maps/public/index.scss b/x-pack/legacy/plugins/maps/public/index.scss index 328b2e576e0e6..b2ac514299d80 100644 --- a/x-pack/legacy/plugins/maps/public/index.scss +++ b/x-pack/legacy/plugins/maps/public/index.scss @@ -14,4 +14,4 @@ @import './mapbox_hacks'; @import './connected_components/index'; @import './components/index'; -@import './layers/index'; +@import '../../../../plugins/maps/public/layers/index'; diff --git a/x-pack/legacy/plugins/maps/public/index.ts b/x-pack/legacy/plugins/maps/public/index.ts index 2d13f005f1a70..b69485e251be4 100644 --- a/x-pack/legacy/plugins/maps/public/index.ts +++ b/x-pack/legacy/plugins/maps/public/index.ts @@ -26,5 +26,9 @@ export const plugin = (initializerContext: PluginInitializerContext) => { return new MapsPlugin(); }; -export { RenderTooltipContentParams, ITooltipProperty } from './layers/tooltips/tooltip_property'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +export { + RenderTooltipContentParams, + ITooltipProperty, +} from '../../../../plugins/maps/public/layers/tooltips/tooltip_property'; export { MapEmbeddable, MapEmbeddableInput } from './embeddable'; diff --git a/x-pack/legacy/plugins/maps/public/kibana_services.js b/x-pack/legacy/plugins/maps/public/kibana_services.js index 3b0f501dc0f60..a6491fe1aa6d4 100644 --- a/x-pack/legacy/plugins/maps/public/kibana_services.js +++ b/x-pack/legacy/plugins/maps/public/kibana_services.js @@ -4,88 +4,26 @@ * you may not use this file except in compliance with the Elastic License. */ -import { esFilters, search } from '../../../../../src/plugins/data/public'; -const { getRequestInspectorStats, getResponseInspectorStats } = search; - -export const SPATIAL_FILTER_TYPE = esFilters.FILTERS.SPATIAL_FILTER; -export { SearchSource } from '../../../../../src/plugins/data/public'; - let indexPatternService; export const setIndexPatternService = dataIndexPatterns => (indexPatternService = dataIndexPatterns); export const getIndexPatternService = () => indexPatternService; -let autocompleteService; -export const setAutocompleteService = dataAutoComplete => (autocompleteService = dataAutoComplete); -export const getAutocompleteService = () => autocompleteService; - -let licenseId; -export const setLicenseId = latestLicenseId => (licenseId = latestLicenseId); -export const getLicenseId = () => { - return licenseId; -}; - let inspector; export const setInspector = newInspector => (inspector = newInspector); export const getInspector = () => { return inspector; }; -let fileUploadPlugin; -export const setFileUpload = fileUpload => (fileUploadPlugin = fileUpload); -export const getFileUploadComponent = () => { - return fileUploadPlugin.JsonUploadAndParse; -}; - let getInjectedVar; export const setInjectedVarFunc = getInjectedVarFunc => (getInjectedVar = getInjectedVarFunc); export const getInjectedVarFunc = () => getInjectedVar; -let uiSettings; -export const setUiSettings = coreUiSettings => (uiSettings = coreUiSettings); -export const getUiSettings = () => uiSettings; - let indexPatternSelectComponent; export const setIndexPatternSelect = indexPatternSelect => (indexPatternSelectComponent = indexPatternSelect); export const getIndexPatternSelectComponent = () => indexPatternSelectComponent; -let coreHttp; -export const setHttp = http => (coreHttp = http); -export const getHttp = () => coreHttp; - let dataTimeFilter; export const setTimeFilter = timeFilter => (dataTimeFilter = timeFilter); export const getTimeFilter = () => dataTimeFilter; - -let toast; -export const setToasts = notificationToast => (toast = notificationToast); -export const getToasts = () => toast; - -export async function fetchSearchSourceAndRecordWithInspector({ - searchSource, - requestId, - requestName, - requestDesc, - inspectorAdapters, - abortSignal, -}) { - const inspectorRequest = inspectorAdapters.requests.start(requestName, { - id: requestId, - description: requestDesc, - }); - let resp; - try { - inspectorRequest.stats(getRequestInspectorStats(searchSource)); - searchSource.getSearchRequestBody().then(body => { - inspectorRequest.json(body); - }); - resp = await searchSource.fetch({ abortSignal }); - inspectorRequest.stats(getResponseInspectorStats(searchSource, resp)).ok({ json: resp }); - } catch (error) { - inspectorRequest.error({ error }); - throw error; - } - - return resp; -} diff --git a/x-pack/legacy/plugins/maps/public/layers/_index.scss b/x-pack/legacy/plugins/maps/public/layers/_index.scss deleted file mode 100644 index a2ce58e0381af..0000000000000 --- a/x-pack/legacy/plugins/maps/public/layers/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './styles/index'; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/_index.scss b/x-pack/legacy/plugins/maps/public/layers/styles/_index.scss deleted file mode 100644 index b5d9113619c76..0000000000000 --- a/x-pack/legacy/plugins/maps/public/layers/styles/_index.scss +++ /dev/null @@ -1,4 +0,0 @@ -@import './components/color_gradient'; -@import './vector/components/style_prop_editor'; -@import './vector/components/color/color_stops'; -@import './vector/components/symbol/icon_select'; diff --git a/x-pack/legacy/plugins/maps/public/plugin.ts b/x-pack/legacy/plugins/maps/public/plugin.ts index c08ed6fc6da61..0fa7e1106a6df 100644 --- a/x-pack/legacy/plugins/maps/public/plugin.ts +++ b/x-pack/legacy/plugins/maps/public/plugin.ts @@ -4,9 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import './layers/layer_wizard_registry'; -import './layers/sources/source_registry'; -import './layers/load_layer_wizards'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import '../../../../plugins/maps/public/layers/layer_wizard_registry'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import '../../../../plugins/maps/public/layers/sources/source_registry'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import '../../../../plugins/maps/public/layers/load_layer_wizards'; import { Plugin, CoreStart, CoreSetup } from 'src/core/public'; // @ts-ignore @@ -17,20 +20,17 @@ import { Start as InspectorStartContract } from 'src/plugins/inspector/public'; import { MapListing } from './components/map_listing'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { - setLicenseId, setInspector, - setFileUpload, setIndexPatternSelect, - setHttp, setTimeFilter, - setUiSettings, setInjectedVarFunc, - setToasts, setIndexPatternService, - setAutocompleteService, } from './kibana_services'; // @ts-ignore -import { setInjectedVarFunc as npSetInjectedVarFunc } from '../../../../plugins/maps/public/kibana_services'; // eslint-disable-line @kbn/eslint/no-restricted-paths +import { + bindSetupCoreAndPlugins as bindNpSetupCoreAndPlugins, + bindStartCoreAndPlugins as bindNpStartCoreAndPlugins, +} from '../../../../plugins/maps/public/plugin'; // eslint-disable-line @kbn/eslint/no-restricted-paths import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public'; import { LicensingPluginSetup } from '../../../../plugins/licensing/public'; import { featureCatalogueEntry } from './feature_catalogue_entry'; @@ -63,27 +63,17 @@ interface MapsPluginStartDependencies { } export const bindSetupCoreAndPlugins = (core: CoreSetup, plugins: any) => { - const { licensing } = plugins; - const { injectedMetadata, http } = core; - if (licensing) { - licensing.license$.subscribe(({ uid }: { uid: string }) => setLicenseId(uid)); - } + const { injectedMetadata } = core; setInjectedVarFunc(injectedMetadata.getInjectedVar); - setHttp(http); - setUiSettings(core.uiSettings); setInjectedVarFunc(core.injectedMetadata.getInjectedVar); - npSetInjectedVarFunc(core.injectedMetadata.getInjectedVar); - setToasts(core.notifications.toasts); }; export const bindStartCoreAndPlugins = (core: CoreStart, plugins: any) => { - const { file_upload, data, inspector } = plugins; + const { data, inspector } = plugins; setInspector(inspector); - setFileUpload(file_upload); setIndexPatternSelect(data.ui.IndexPatternSelect); setTimeFilter(data.query.timefilter.timefilter); setIndexPatternService(data.indexPatterns); - setAutocompleteService(data.autocomplete); }; /** @internal */ @@ -96,11 +86,13 @@ export class MapsPlugin implements Plugin { }); bindSetupCoreAndPlugins(core, np); + bindNpSetupCoreAndPlugins(core, np); np.home.featureCatalogue.register(featureCatalogueEntry); } public start(core: CoreStart, plugins: MapsPluginStartDependencies) { bindStartCoreAndPlugins(core, plugins); + bindNpStartCoreAndPlugins(core, plugins); } } diff --git a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js b/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js index 397478cfd1d1b..59346e4c6fb98 100644 --- a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js +++ b/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js @@ -6,11 +6,16 @@ import { createSelector } from 'reselect'; import _ from 'lodash'; -import { TileLayer } from '../layers/tile_layer'; -import { VectorTileLayer } from '../layers/vector_tile_layer'; -import { VectorLayer } from '../layers/vector_layer'; -import { HeatmapLayer } from '../layers/heatmap_layer'; -import { BlendedVectorLayer } from '../layers/blended_vector_layer'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { TileLayer } from '../../../../../plugins/maps/public/layers/tile_layer'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { VectorTileLayer } from '../../../../../plugins/maps/public/layers/vector_tile_layer'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { VectorLayer } from '../../../../../plugins/maps/public/layers/vector_layer'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { HeatmapLayer } from '../../../../../plugins/maps/public/layers/heatmap_layer'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { BlendedVectorLayer } from '../../../../../plugins/maps/public/layers/blended_vector_layer'; import { getTimeFilter } from '../kibana_services'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { getInspectorAdapters } from '../../../../../plugins/maps/public/reducers/non_serializable_instances'; @@ -19,8 +24,10 @@ import { TRACKED_LAYER_DESCRIPTOR, // eslint-disable-next-line @kbn/eslint/no-restricted-paths } from '../../../../../plugins/maps/public/reducers/util'; -import { InnerJoin } from '../layers/joins/inner_join'; -import { getSourceByType } from '../layers/sources/source_registry'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { InnerJoin } from '../../../../../plugins/maps/public/layers/joins/inner_join'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getSourceByType } from '../../../../../plugins/maps/public/layers/sources/source_registry'; function createLayerInstance(layerDescriptor, inspectorAdapters) { const source = createSourceInstance(layerDescriptor.sourceDescriptor, inspectorAdapters); diff --git a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.test.js b/x-pack/legacy/plugins/maps/public/selectors/map_selectors.test.js index 1a5ab633a569f..77bd29259647c 100644 --- a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.test.js +++ b/x-pack/legacy/plugins/maps/public/selectors/map_selectors.test.js @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -jest.mock('../layers/vector_layer', () => {}); -jest.mock('../layers/blended_vector_layer', () => {}); -jest.mock('../layers/heatmap_layer', () => {}); -jest.mock('../layers/vector_tile_layer', () => {}); -jest.mock('../layers/joins/inner_join', () => {}); +jest.mock('../../../../../plugins/maps/public/layers/vector_layer', () => {}); +jest.mock('../../../../../plugins/maps/public/layers/blended_vector_layer', () => {}); +jest.mock('../../../../../plugins/maps/public/layers/heatmap_layer', () => {}); +jest.mock('../../../../../plugins/maps/public/layers/vector_tile_layer', () => {}); +jest.mock('../../../../../plugins/maps/public/layers/joins/inner_join', () => {}); jest.mock('../../../../../plugins/maps/public/reducers/non_serializable_instances', () => ({ getInspectorAdapters: () => { return {}; diff --git a/x-pack/plugins/maps/public/actions/map_actions.d.ts b/x-pack/plugins/maps/public/actions/map_actions.d.ts new file mode 100644 index 0000000000000..debead3ad5c45 --- /dev/null +++ b/x-pack/plugins/maps/public/actions/map_actions.d.ts @@ -0,0 +1,64 @@ +/* + * 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. + */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ + +import { Filter, Query, TimeRange } from 'src/plugins/data/public'; +import { AnyAction } from 'redux'; +import { LAYER_TYPE } from '../../common/constants'; +import { + DataMeta, + MapFilters, + MapCenterAndZoom, + MapRefreshConfig, +} from '../../common/descriptor_types'; + +export type SyncContext = { + startLoading(dataId: string, requestToken: symbol, meta: DataMeta): void; + stopLoading(dataId: string, requestToken: symbol, data: unknown, meta: DataMeta): void; + onLoadError(dataId: string, requestToken: symbol, errorMessage: string): void; + updateSourceData(newData: unknown): void; + isRequestStillActive(dataId: string, requestToken: symbol): boolean; + registerCancelCallback(requestToken: symbol, callback: () => void): void; + dataFilters: MapFilters; +}; + +export function updateSourceProp( + layerId: string, + propName: string, + value: unknown, + newLayerType?: LAYER_TYPE +): void; + +export function setGotoWithCenter(config: MapCenterAndZoom): AnyAction; + +export function replaceLayerList(layerList: unknown[]): AnyAction; + +export type QueryGroup = { + filters: Filter[]; + query?: Query; + timeFilters?: TimeRange; + refresh?: boolean; +}; + +export function setQuery(query: QueryGroup): AnyAction; + +export function setRefreshConfig(config: MapRefreshConfig): AnyAction; + +export function disableScrollZoom(): AnyAction; + +export function disableInteractive(): AnyAction; + +export function disableTooltipControl(): AnyAction; + +export function hideToolbarOverlay(): AnyAction; + +export function hideLayerControl(): AnyAction; + +export function hideViewControl(): AnyAction; + +export function setHiddenLayers(hiddenLayerIds: string[]): AnyAction; + +export function addLayerWithoutDataSync(layerDescriptor: unknown): AnyAction; diff --git a/x-pack/legacy/plugins/maps/public/components/__snapshots__/add_tooltip_field_popover.test.js.snap b/x-pack/plugins/maps/public/components/__snapshots__/add_tooltip_field_popover.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/__snapshots__/add_tooltip_field_popover.test.js.snap rename to x-pack/plugins/maps/public/components/__snapshots__/add_tooltip_field_popover.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/components/__snapshots__/tooltip_selector.test.js.snap b/x-pack/plugins/maps/public/components/__snapshots__/tooltip_selector.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/__snapshots__/tooltip_selector.test.js.snap rename to x-pack/plugins/maps/public/components/__snapshots__/tooltip_selector.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/components/__snapshots__/validated_range.test.js.snap b/x-pack/plugins/maps/public/components/__snapshots__/validated_range.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/__snapshots__/validated_range.test.js.snap rename to x-pack/plugins/maps/public/components/__snapshots__/validated_range.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/components/add_tooltip_field_popover.js b/x-pack/plugins/maps/public/components/add_tooltip_field_popover.js similarity index 98% rename from x-pack/legacy/plugins/maps/public/components/add_tooltip_field_popover.js rename to x-pack/plugins/maps/public/components/add_tooltip_field_popover.js index 07bc54663c1d8..984ace4fd8708 100644 --- a/x-pack/legacy/plugins/maps/public/components/add_tooltip_field_popover.js +++ b/x-pack/plugins/maps/public/components/add_tooltip_field_popover.js @@ -17,7 +17,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { FieldIcon } from '../../../../../../src/plugins/kibana_react/public'; +import { FieldIcon } from '../../../../../src/plugins/kibana_react/public'; const sortByLabel = (a, b) => { return a.label.localeCompare(b.label); diff --git a/x-pack/legacy/plugins/maps/public/components/add_tooltip_field_popover.test.js b/x-pack/plugins/maps/public/components/add_tooltip_field_popover.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/add_tooltip_field_popover.test.js rename to x-pack/plugins/maps/public/components/add_tooltip_field_popover.test.js diff --git a/x-pack/legacy/plugins/maps/public/components/metric_editor.js b/x-pack/plugins/maps/public/components/metric_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/metric_editor.js rename to x-pack/plugins/maps/public/components/metric_editor.js diff --git a/x-pack/legacy/plugins/maps/public/components/metric_select.js b/x-pack/plugins/maps/public/components/metric_select.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/metric_select.js rename to x-pack/plugins/maps/public/components/metric_select.js diff --git a/x-pack/legacy/plugins/maps/public/components/metrics_editor.js b/x-pack/plugins/maps/public/components/metrics_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/components/metrics_editor.js rename to x-pack/plugins/maps/public/components/metrics_editor.js diff --git a/x-pack/legacy/plugins/maps/public/components/no_index_pattern_callout.js b/x-pack/plugins/maps/public/components/no_index_pattern_callout.js similarity index 85% rename from x-pack/legacy/plugins/maps/public/components/no_index_pattern_callout.js rename to x-pack/plugins/maps/public/components/no_index_pattern_callout.js index 3266f13155ca7..1319607546808 100644 --- a/x-pack/legacy/plugins/maps/public/components/no_index_pattern_callout.js +++ b/x-pack/plugins/maps/public/components/no_index_pattern_callout.js @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import chrome from 'ui/chrome'; - +import { getHttp } from '../kibana_services'; import React from 'react'; import { EuiCallOut, EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; export function NoIndexPatternCallout() { + const http = getHttp(); return ( - + - + { + const image = new Image(); + if (isCrossOriginUrl(imgUrl)) { + image.crossOrigin = 'Anonymous'; + } + image.onload = el => { + const imgData = getImageData(el.currentTarget); + resolve(imgData); + }; + image.onerror = e => { + reject(e); + }; + image.src = imgUrl; + }); +} + +export function addSpriteSheetToMapFromImageData(json, imgData, mbMap) { + for (const imageId in json) { + if (!(json.hasOwnProperty(imageId) && !mbMap.hasImage(imageId))) { + continue; + } + const { width, height, x, y, sdf, pixelRatio } = json[imageId]; + if (typeof width !== 'number' || typeof height !== 'number') { + continue; + } + + const data = new RGBAImage({ width, height }); + RGBAImage.copy(imgData, data, { x, y }, { x: 0, y: 0 }, { width, height }); + mbMap.addImage(imageId, data, { pixelRatio, sdf }); + } +} diff --git a/x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.js rename to x-pack/plugins/maps/public/elasticsearch_geo_utils.js diff --git a/x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.test.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js similarity index 99% rename from x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.test.js rename to x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js index fb4b0a6e29e6c..5db7556be4639 100644 --- a/x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.test.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js @@ -20,7 +20,7 @@ import { convertMapExtentToPolygon, roundCoordinates, } from './elasticsearch_geo_utils'; -import { indexPatterns } from '../../../../../src/plugins/data/public'; +import { indexPatterns } from '../../../../src/plugins/data/public'; const geoFieldName = 'location'; const mapExtent = { diff --git a/x-pack/legacy/plugins/maps/public/index_pattern_util.js b/x-pack/plugins/maps/public/index_pattern_util.js similarity index 95% rename from x-pack/legacy/plugins/maps/public/index_pattern_util.js rename to x-pack/plugins/maps/public/index_pattern_util.js index 30a0a6826db83..6cb02c7605e28 100644 --- a/x-pack/legacy/plugins/maps/public/index_pattern_util.js +++ b/x-pack/plugins/maps/public/index_pattern_util.js @@ -5,7 +5,7 @@ */ import { getIndexPatternService } from './kibana_services'; -import { indexPatterns } from '../../../../../src/plugins/data/public'; +import { indexPatterns } from '../../../../src/plugins/data/public'; import { ES_GEO_FIELD_TYPE } from '../common/constants'; export async function getIndexPatternsFromIds(indexPatternIds = []) { diff --git a/x-pack/legacy/plugins/maps/public/index_pattern_util.test.js b/x-pack/plugins/maps/public/index_pattern_util.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/index_pattern_util.test.js rename to x-pack/plugins/maps/public/index_pattern_util.test.js diff --git a/x-pack/plugins/maps/public/kibana_services.js b/x-pack/plugins/maps/public/kibana_services.js index 1073e44fa711e..d2ddecfdf915b 100644 --- a/x-pack/plugins/maps/public/kibana_services.js +++ b/x-pack/plugins/maps/public/kibana_services.js @@ -3,7 +3,89 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { esFilters, search } from '../../../../src/plugins/data/public'; + +export { SearchSource } from '../../../../src/plugins/data/public'; + +export const SPATIAL_FILTER_TYPE = esFilters.FILTERS.SPATIAL_FILTER; +const { getRequestInspectorStats, getResponseInspectorStats } = search; + +let indexPatternService; +export const setIndexPatternService = dataIndexPatterns => + (indexPatternService = dataIndexPatterns); +export const getIndexPatternService = () => indexPatternService; + +let autocompleteService; +export const setAutocompleteService = dataAutoComplete => (autocompleteService = dataAutoComplete); +export const getAutocompleteService = () => autocompleteService; + +let licenseId; +export const setLicenseId = latestLicenseId => (licenseId = latestLicenseId); +export const getLicenseId = () => { + return licenseId; +}; + +let inspector; +export const setInspector = newInspector => (inspector = newInspector); +export const getInspector = () => { + return inspector; +}; + +let fileUploadPlugin; +export const setFileUpload = fileUpload => (fileUploadPlugin = fileUpload); +export const getFileUploadComponent = () => { + return fileUploadPlugin.JsonUploadAndParse; +}; let getInjectedVar; export const setInjectedVarFunc = getInjectedVarFunc => (getInjectedVar = getInjectedVarFunc); export const getInjectedVarFunc = () => getInjectedVar; + +let uiSettings; +export const setUiSettings = coreUiSettings => (uiSettings = coreUiSettings); +export const getUiSettings = () => uiSettings; + +let indexPatternSelectComponent; +export const setIndexPatternSelect = indexPatternSelect => + (indexPatternSelectComponent = indexPatternSelect); +export const getIndexPatternSelectComponent = () => indexPatternSelectComponent; + +let coreHttp; +export const setHttp = http => (coreHttp = http); +export const getHttp = () => coreHttp; + +let dataTimeFilter; +export const setTimeFilter = timeFilter => (dataTimeFilter = timeFilter); +export const getTimeFilter = () => dataTimeFilter; + +let toast; +export const setToasts = notificationToast => (toast = notificationToast); +export const getToasts = () => toast; + +export async function fetchSearchSourceAndRecordWithInspector({ + searchSource, + requestId, + requestName, + requestDesc, + inspectorAdapters, + abortSignal, +}) { + const inspectorRequest = inspectorAdapters.requests.start(requestName, { + id: requestId, + description: requestDesc, + }); + let resp; + try { + inspectorRequest.stats(getRequestInspectorStats(searchSource)); + searchSource.getSearchRequestBody().then(body => { + inspectorRequest.json(body); + }); + resp = await searchSource.fetch({ abortSignal }); + inspectorRequest.stats(getResponseInspectorStats(searchSource, resp)).ok({ json: resp }); + } catch (error) { + inspectorRequest.error({ error }); + throw error; + } + + return resp; +} diff --git a/x-pack/plugins/maps/public/layers/_index.scss b/x-pack/plugins/maps/public/layers/_index.scss new file mode 100644 index 0000000000000..29a5761255278 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/_index.scss @@ -0,0 +1 @@ +@import 'styles/index'; diff --git a/x-pack/legacy/plugins/maps/public/layers/blended_vector_layer.ts b/x-pack/plugins/maps/public/layers/blended_vector_layer.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/blended_vector_layer.ts rename to x-pack/plugins/maps/public/layers/blended_vector_layer.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/ems_file_field.ts b/x-pack/plugins/maps/public/layers/fields/ems_file_field.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/fields/ems_file_field.ts rename to x-pack/plugins/maps/public/layers/fields/ems_file_field.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.test.ts b/x-pack/plugins/maps/public/layers/fields/es_agg_field.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.test.ts rename to x-pack/plugins/maps/public/layers/fields/es_agg_field.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.ts b/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.ts rename to x-pack/plugins/maps/public/layers/fields/es_agg_field.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/es_doc_field.ts b/x-pack/plugins/maps/public/layers/fields/es_doc_field.ts similarity index 96% rename from x-pack/legacy/plugins/maps/public/layers/fields/es_doc_field.ts rename to x-pack/plugins/maps/public/layers/fields/es_doc_field.ts index 4401452841a46..b7647d881fcf6 100644 --- a/x-pack/legacy/plugins/maps/public/layers/fields/es_doc_field.ts +++ b/x-pack/plugins/maps/public/layers/fields/es_doc_field.ts @@ -8,8 +8,8 @@ import { FIELD_ORIGIN } from '../../../common/constants'; import { ESTooltipProperty } from '../tooltips/es_tooltip_property'; import { ITooltipProperty, TooltipProperty } from '../tooltips/tooltip_property'; import { COLOR_PALETTE_MAX_SIZE } from '../../../common/constants'; -import { indexPatterns } from '../../../../../../../src/plugins/data/public'; -import { IFieldType } from '../../../../../../../src/plugins/data/public'; +import { indexPatterns } from '../../../../../../src/plugins/data/public'; +import { IFieldType } from '../../../../../../src/plugins/data/public'; import { IField, AbstractField } from './field'; import { IESSource } from '../sources/es_source'; import { IVectorSource } from '../sources/vector_source'; diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/field.ts b/x-pack/plugins/maps/public/layers/fields/field.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/fields/field.ts rename to x-pack/plugins/maps/public/layers/fields/field.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/kibana_region_field.ts b/x-pack/plugins/maps/public/layers/fields/kibana_region_field.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/fields/kibana_region_field.ts rename to x-pack/plugins/maps/public/layers/fields/kibana_region_field.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/top_term_percentage_field.ts b/x-pack/plugins/maps/public/layers/fields/top_term_percentage_field.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/fields/top_term_percentage_field.ts rename to x-pack/plugins/maps/public/layers/fields/top_term_percentage_field.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/heatmap_layer.js b/x-pack/plugins/maps/public/layers/heatmap_layer.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/heatmap_layer.js rename to x-pack/plugins/maps/public/layers/heatmap_layer.js diff --git a/x-pack/legacy/plugins/maps/public/layers/joins/inner_join.js b/x-pack/plugins/maps/public/layers/joins/inner_join.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/joins/inner_join.js rename to x-pack/plugins/maps/public/layers/joins/inner_join.js diff --git a/x-pack/legacy/plugins/maps/public/layers/joins/inner_join.test.js b/x-pack/plugins/maps/public/layers/joins/inner_join.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/joins/inner_join.test.js rename to x-pack/plugins/maps/public/layers/joins/inner_join.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/joins/join.ts b/x-pack/plugins/maps/public/layers/joins/join.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/joins/join.ts rename to x-pack/plugins/maps/public/layers/joins/join.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/layer.d.ts b/x-pack/plugins/maps/public/layers/layer.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/layer.d.ts rename to x-pack/plugins/maps/public/layers/layer.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/layer.js b/x-pack/plugins/maps/public/layers/layer.js similarity index 99% rename from x-pack/legacy/plugins/maps/public/layers/layer.js rename to x-pack/plugins/maps/public/layers/layer.js index e9616be89b601..26bce872b3c2c 100644 --- a/x-pack/legacy/plugins/maps/public/layers/layer.js +++ b/x-pack/plugins/maps/public/layers/layer.js @@ -15,7 +15,7 @@ import { } from '../../common/constants'; import uuid from 'uuid/v4'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { copyPersistentState } from '../../../../../plugins/maps/public/reducers/util.js'; +import { copyPersistentState } from '../reducers/util.js'; import { i18n } from '@kbn/i18n'; export class AbstractLayer { diff --git a/x-pack/legacy/plugins/maps/public/layers/layer_wizard_registry.ts b/x-pack/plugins/maps/public/layers/layer_wizard_registry.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/layer_wizard_registry.ts rename to x-pack/plugins/maps/public/layers/layer_wizard_registry.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/load_layer_wizards.js b/x-pack/plugins/maps/public/layers/load_layer_wizards.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/load_layer_wizards.js rename to x-pack/plugins/maps/public/layers/load_layer_wizards.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/create_client_file_source_editor.js b/x-pack/plugins/maps/public/layers/sources/client_file_source/create_client_file_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/create_client_file_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/client_file_source/create_client_file_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js b/x-pack/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js rename to x-pack/plugins/maps/public/layers/sources/client_file_source/geojson_file_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/index.js b/x-pack/plugins/maps/public/layers/sources/client_file_source/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/client_file_source/index.js rename to x-pack/plugins/maps/public/layers/sources/client_file_source/index.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/create_source_editor.js b/x-pack/plugins/maps/public/layers/sources/ems_file_source/create_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/create_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/ems_file_source/create_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.d.ts b/x-pack/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.js b/x-pack/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.js rename to x-pack/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.test.js b/x-pack/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.test.js rename to x-pack/plugins/maps/public/layers/sources/ems_file_source/ems_file_source.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/index.js b/x-pack/plugins/maps/public/layers/sources/ems_file_source/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/index.js rename to x-pack/plugins/maps/public/layers/sources/ems_file_source/index.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/update_source_editor.js b/x-pack/plugins/maps/public/layers/sources/ems_file_source/update_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_file_source/update_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/ems_file_source/update_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.js b/x-pack/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.js rename to x-pack/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.test.js b/x-pack/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.test.js rename to x-pack/plugins/maps/public/layers/sources/ems_tms_source/ems_tms_source.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/index.js b/x-pack/plugins/maps/public/layers/sources/ems_tms_source/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/index.js rename to x-pack/plugins/maps/public/layers/sources/ems_tms_source/index.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/tile_service_select.js b/x-pack/plugins/maps/public/layers/sources/ems_tms_source/tile_service_select.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/tile_service_select.js rename to x-pack/plugins/maps/public/layers/sources/ems_tms_source/tile_service_select.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/update_source_editor.js b/x-pack/plugins/maps/public/layers/sources/ems_tms_source/update_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_tms_source/update_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/ems_tms_source/update_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/ems_unavailable_message.js b/x-pack/plugins/maps/public/layers/sources/ems_unavailable_message.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/ems_unavailable_message.js rename to x-pack/plugins/maps/public/layers/sources/ems_unavailable_message.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.d.ts b/x-pack/plugins/maps/public/layers/sources/es_agg_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/es_agg_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js b/x-pack/plugins/maps/public/layers/sources/es_agg_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js rename to x-pack/plugins/maps/public/layers/sources/es_agg_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.test.ts b/x-pack/plugins/maps/public/layers/sources/es_agg_source.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.test.ts rename to x-pack/plugins/maps/public/layers/sources/es_agg_source.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.d.ts b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.test.ts b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.test.ts rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/index.js b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/index.js rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/index.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/render_as_select.tsx b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/render_as_select.tsx similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/render_as_select.tsx rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/render_as_select.tsx diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/resolution_editor.js b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/resolution_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/resolution_editor.js rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/resolution_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js similarity index 97% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js index 269c2a8b8633a..cd494db3897fb 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js +++ b/x-pack/plugins/maps/public/layers/sources/es_geo_grid_source/update_source_editor.js @@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { isMetricCountable } from '../../util/is_metric_countable'; -import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; +import { indexPatterns } from '../../../../../../../src/plugins/data/public'; export class UpdateSourceEditor extends Component { state = { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js b/x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js rename to x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts b/x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts rename to x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/create_source_editor.js b/x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/create_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/create_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/create_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js b/x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js similarity index 98% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js rename to x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js index da2b663746b9d..ea3a2d2fe634d 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js +++ b/x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js @@ -25,7 +25,7 @@ import { convertToLines } from './convert_to_lines'; import { AbstractESAggSource } from '../es_agg_source'; import { DynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property'; import { COLOR_GRADIENTS } from '../../styles/color_utils'; -import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; +import { indexPatterns } from '../../../../../../../src/plugins/data/public'; import { registerSource } from '../source_registry'; const MAX_GEOTILE_LEVEL = 29; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js b/x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js similarity index 96% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js index ce1f53c33ba53..dea59a1c82f8a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js +++ b/x-pack/plugins/maps/public/layers/sources/es_pew_pew_source/update_source_editor.js @@ -11,7 +11,7 @@ import { getIndexPatternService } from '../../../kibana_services'; import { i18n } from '@kbn/i18n'; import { EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; +import { indexPatterns } from '../../../../../../../src/plugins/data/public'; export class UpdateSourceEditor extends Component { state = { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap b/x-pack/plugins/maps/public/layers/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap rename to x-pack/plugins/maps/public/layers/sources/es_search_source/__snapshots__/scaling_form.test.tsx.snap diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap b/x-pack/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap rename to x-pack/plugins/maps/public/layers/sources/es_search_source/__snapshots__/update_source_editor.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/constants.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/constants.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/constants.js rename to x-pack/plugins/maps/public/layers/sources/es_search_source/constants.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js similarity index 98% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js index 73bea574ace28..aeb3835354f07 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js @@ -15,7 +15,7 @@ import { NoIndexPatternCallout } from '../../../components/no_index_pattern_call import { i18n } from '@kbn/i18n'; import { ES_GEO_FIELD_TYPE, SCALING_TYPES } from '../../../../common/constants'; import { DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants'; -import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; +import { indexPatterns } from '../../../../../../../src/plugins/data/public'; import { ScalingForm } from './scaling_form'; import { getTermsFields } from '../../../index_pattern_util'; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.d.ts b/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js rename to x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.test.ts b/x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.test.ts rename to x-pack/plugins/maps/public/layers/sources/es_search_source/es_search_source.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/index.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/index.js rename to x-pack/plugins/maps/public/layers/sources/es_search_source/index.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/load_index_settings.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/load_index_settings.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/load_index_settings.js rename to x-pack/plugins/maps/public/layers/sources/es_search_source/load_index_settings.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/scaling_form.test.tsx b/x-pack/plugins/maps/public/layers/sources/es_search_source/scaling_form.test.tsx similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/scaling_form.test.tsx rename to x-pack/plugins/maps/public/layers/sources/es_search_source/scaling_form.test.tsx diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/scaling_form.tsx b/x-pack/plugins/maps/public/layers/sources/es_search_source/scaling_form.tsx similarity index 97% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/scaling_form.tsx rename to x-pack/plugins/maps/public/layers/sources/es_search_source/scaling_form.tsx index c5950f1132974..d86fc6d4026e6 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/scaling_form.tsx +++ b/x-pack/plugins/maps/public/layers/sources/es_search_source/scaling_form.tsx @@ -22,8 +22,6 @@ import { SingleFieldSelect } from '../../../components/single_field_select'; // @ts-ignore import { indexPatternService } from '../../../kibana_services'; // @ts-ignore -import { getTermsFields, getSourceFields } from '../../../index_pattern_util'; -// @ts-ignore import { ValidatedRange } from '../../../components/validated_range'; import { DEFAULT_MAX_INNER_RESULT_WINDOW, @@ -33,7 +31,7 @@ import { } from '../../../../common/constants'; // @ts-ignore import { loadIndexSettings } from './load_index_settings'; -import { IFieldType } from '../../../../../../../../src/plugins/data/public'; +import { IFieldType } from '../../../../../../../src/plugins/data/public'; import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/view'; interface Props { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js similarity index 98% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js index 9c92ec5801e49..cb6255afd0a42 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js +++ b/x-pack/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js @@ -16,7 +16,7 @@ import { getTermsFields, getSourceFields } from '../../../index_pattern_util'; import { SORT_ORDER } from '../../../../common/constants'; import { ESDocField } from '../../fields/es_doc_field'; import { FormattedMessage } from '@kbn/i18n/react'; -import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; +import { indexPatterns } from '../../../../../../../src/plugins/data/public'; import { ScalingForm } from './scaling_form'; export class UpdateSourceEditor extends Component { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.test.js b/x-pack/plugins/maps/public/layers/sources/es_search_source/update_source_editor.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.test.js rename to x-pack/plugins/maps/public/layers/sources/es_search_source/update_source_editor.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.d.ts b/x-pack/plugins/maps/public/layers/sources/es_source.d.ts similarity index 92% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/es_source.d.ts index ffd1d343b59e0..65851d0e7bd38 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.d.ts +++ b/x-pack/plugins/maps/public/layers/sources/es_source.d.ts @@ -6,7 +6,7 @@ import { AbstractVectorSource } from './vector_source'; import { IVectorSource } from './vector_source'; -import { IndexPattern, SearchSource } from '../../../../../../../src/plugins/data/public'; +import { IndexPattern, SearchSource } from '../../../../../../src/plugins/data/public'; import { VectorSourceRequestMeta } from '../../../common/descriptor_types'; export interface IESSource extends IVectorSource { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js b/x-pack/plugins/maps/public/layers/sources/es_source.js similarity index 99% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_source.js rename to x-pack/plugins/maps/public/layers/sources/es_source.js index 441d52d23398a..d90a802a38344 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js +++ b/x-pack/plugins/maps/public/layers/sources/es_source.js @@ -17,7 +17,7 @@ import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { copyPersistentState } from '../../../../../../plugins/maps/public/reducers/util'; +import { copyPersistentState } from '../../reducers/util'; import { ES_GEO_FIELD_TYPE } from '../../../common/constants'; import { DataRequestAbortError } from '../util/data_request'; import { expandToTileBoundaries } from './es_geo_grid_source/geo_tile_utils'; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.d.ts b/x-pack/plugins/maps/public/layers/sources/es_term_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/es_term_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.js b/x-pack/plugins/maps/public/layers/sources/es_term_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.js rename to x-pack/plugins/maps/public/layers/sources/es_term_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.test.js b/x-pack/plugins/maps/public/layers/sources/es_term_source.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.test.js rename to x-pack/plugins/maps/public/layers/sources/es_term_source.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/kibana_regionmap_source/create_source_editor.js b/x-pack/plugins/maps/public/layers/sources/kibana_regionmap_source/create_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/kibana_regionmap_source/create_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/kibana_regionmap_source/create_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/kibana_regionmap_source/index.js b/x-pack/plugins/maps/public/layers/sources/kibana_regionmap_source/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/kibana_regionmap_source/index.js rename to x-pack/plugins/maps/public/layers/sources/kibana_regionmap_source/index.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.d.ts b/x-pack/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js b/x-pack/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js rename to x-pack/plugins/maps/public/layers/sources/kibana_regionmap_source/kibana_regionmap_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/kibana_tilemap_source/create_source_editor.js b/x-pack/plugins/maps/public/layers/sources/kibana_tilemap_source/create_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/kibana_tilemap_source/create_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/kibana_tilemap_source/create_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/kibana_tilemap_source/index.js b/x-pack/plugins/maps/public/layers/sources/kibana_tilemap_source/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/kibana_tilemap_source/index.js rename to x-pack/plugins/maps/public/layers/sources/kibana_tilemap_source/index.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js b/x-pack/plugins/maps/public/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js rename to x-pack/plugins/maps/public/layers/sources/kibana_tilemap_source/kibana_tilemap_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/source.d.ts b/x-pack/plugins/maps/public/layers/sources/source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/source.d.ts rename to x-pack/plugins/maps/public/layers/sources/source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/source.js b/x-pack/plugins/maps/public/layers/sources/source.js similarity index 96% rename from x-pack/legacy/plugins/maps/public/layers/sources/source.js rename to x-pack/plugins/maps/public/layers/sources/source.js index b6b6c10831bb5..368de421e23ce 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/source.js +++ b/x-pack/plugins/maps/public/layers/sources/source.js @@ -5,7 +5,7 @@ */ // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { copyPersistentState } from '../../../../../../plugins/maps/public/reducers/util'; +import { copyPersistentState } from '../../reducers/util'; export class AbstractSource { static isIndexingSource = false; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/source_registry.ts b/x-pack/plugins/maps/public/layers/sources/source_registry.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/source_registry.ts rename to x-pack/plugins/maps/public/layers/sources/source_registry.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/tms_source.d.ts b/x-pack/plugins/maps/public/layers/sources/tms_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/tms_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/tms_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/tms_source.js b/x-pack/plugins/maps/public/layers/sources/tms_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/tms_source.js rename to x-pack/plugins/maps/public/layers/sources/tms_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/vector_feature_types.js b/x-pack/plugins/maps/public/layers/sources/vector_feature_types.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/vector_feature_types.js rename to x-pack/plugins/maps/public/layers/sources/vector_feature_types.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/vector_source.d.ts b/x-pack/plugins/maps/public/layers/sources/vector_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/vector_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/vector_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/vector_source.js b/x-pack/plugins/maps/public/layers/sources/vector_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/vector_source.js rename to x-pack/plugins/maps/public/layers/sources/vector_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/wms_source/index.js b/x-pack/plugins/maps/public/layers/sources/wms_source/index.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/wms_source/index.js rename to x-pack/plugins/maps/public/layers/sources/wms_source/index.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/wms_source/wms_client.js b/x-pack/plugins/maps/public/layers/sources/wms_source/wms_client.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/wms_source/wms_client.js rename to x-pack/plugins/maps/public/layers/sources/wms_source/wms_client.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/wms_source/wms_client.test.js b/x-pack/plugins/maps/public/layers/sources/wms_source/wms_client.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/wms_source/wms_client.test.js rename to x-pack/plugins/maps/public/layers/sources/wms_source/wms_client.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/wms_source/wms_create_source_editor.js b/x-pack/plugins/maps/public/layers/sources/wms_source/wms_create_source_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/wms_source/wms_create_source_editor.js rename to x-pack/plugins/maps/public/layers/sources/wms_source/wms_create_source_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/wms_source/wms_source.js b/x-pack/plugins/maps/public/layers/sources/wms_source/wms_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/wms_source/wms_source.js rename to x-pack/plugins/maps/public/layers/sources/wms_source/wms_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/xyz_tms_source.d.ts b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/xyz_tms_source.d.ts rename to x-pack/plugins/maps/public/layers/sources/xyz_tms_source.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/xyz_tms_source.js b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/xyz_tms_source.js rename to x-pack/plugins/maps/public/layers/sources/xyz_tms_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/xyz_tms_source.test.ts b/x-pack/plugins/maps/public/layers/sources/xyz_tms_source.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/sources/xyz_tms_source.test.ts rename to x-pack/plugins/maps/public/layers/sources/xyz_tms_source.test.ts diff --git a/x-pack/plugins/maps/public/layers/styles/_index.scss b/x-pack/plugins/maps/public/layers/styles/_index.scss new file mode 100644 index 0000000000000..a1c4c297a3ac1 --- /dev/null +++ b/x-pack/plugins/maps/public/layers/styles/_index.scss @@ -0,0 +1,4 @@ +@import 'components/color_gradient'; +@import 'vector/components/style_prop_editor'; +@import 'vector/components/color/color_stops'; +@import 'vector/components/symbol/icon_select'; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/abstract_style.js b/x-pack/plugins/maps/public/layers/styles/abstract_style.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/abstract_style.js rename to x-pack/plugins/maps/public/layers/styles/abstract_style.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js b/x-pack/plugins/maps/public/layers/styles/color_utils.js similarity index 98% rename from x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js rename to x-pack/plugins/maps/public/layers/styles/color_utils.js index 09c7d76db1691..23b61b07bf871 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js +++ b/x-pack/plugins/maps/public/layers/styles/color_utils.js @@ -10,7 +10,7 @@ import chroma from 'chroma-js'; import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { ColorGradient } from './components/color_gradient'; import { COLOR_PALETTE_MAX_SIZE } from '../../../common/constants'; -import { vislibColorMaps } from '../../../../../../../src/plugins/charts/public'; +import { vislibColorMaps } from '../../../../../../src/plugins/charts/public'; const GRADIENT_INTERVALS = 8; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.test.js b/x-pack/plugins/maps/public/layers/styles/color_utils.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/color_utils.test.js rename to x-pack/plugins/maps/public/layers/styles/color_utils.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/components/_color_gradient.scss b/x-pack/plugins/maps/public/layers/styles/components/_color_gradient.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/components/_color_gradient.scss rename to x-pack/plugins/maps/public/layers/styles/components/_color_gradient.scss diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/components/color_gradient.js b/x-pack/plugins/maps/public/layers/styles/components/color_gradient.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/components/color_gradient.js rename to x-pack/plugins/maps/public/layers/styles/components/color_gradient.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/components/ranged_style_legend_row.js b/x-pack/plugins/maps/public/layers/styles/components/ranged_style_legend_row.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/components/ranged_style_legend_row.js rename to x-pack/plugins/maps/public/layers/styles/components/ranged_style_legend_row.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/__snapshots__/heatmap_style_editor.test.js.snap b/x-pack/plugins/maps/public/layers/styles/heatmap/components/__snapshots__/heatmap_style_editor.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/__snapshots__/heatmap_style_editor.test.js.snap rename to x-pack/plugins/maps/public/layers/styles/heatmap/components/__snapshots__/heatmap_style_editor.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/heatmap_constants.js b/x-pack/plugins/maps/public/layers/styles/heatmap/components/heatmap_constants.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/heatmap_constants.js rename to x-pack/plugins/maps/public/layers/styles/heatmap/components/heatmap_constants.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.js b/x-pack/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.js rename to x-pack/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.test.js b/x-pack/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.test.js rename to x-pack/plugins/maps/public/layers/styles/heatmap/components/heatmap_style_editor.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/legend/heatmap_legend.js b/x-pack/plugins/maps/public/layers/styles/heatmap/components/legend/heatmap_legend.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/heatmap/components/legend/heatmap_legend.js rename to x-pack/plugins/maps/public/layers/styles/heatmap/components/legend/heatmap_legend.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/heatmap/heatmap_style.js b/x-pack/plugins/maps/public/layers/styles/heatmap/heatmap_style.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/heatmap/heatmap_style.js rename to x-pack/plugins/maps/public/layers/styles/heatmap/heatmap_style.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/_style_prop_editor.scss b/x-pack/plugins/maps/public/layers/styles/vector/components/_style_prop_editor.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/_style_prop_editor.scss rename to x-pack/plugins/maps/public/layers/styles/vector/components/_style_prop_editor.scss diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/_color_stops.scss b/x-pack/plugins/maps/public/layers/styles/vector/components/color/_color_stops.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/_color_stops.scss rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/_color_stops.scss diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/color_map_select.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_stops.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/color_stops.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/color_stops_categorical.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/color_stops_ordinal.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_utils.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/color_stops_utils.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/color_stops_utils.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/color_stops_utils.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/dynamic_color_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/mb_validated_color_picker.tsx b/x-pack/plugins/maps/public/layers/styles/vector/components/color/mb_validated_color_picker.tsx similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/mb_validated_color_picker.tsx rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/mb_validated_color_picker.tsx diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/static_color_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/vector_style_color_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/color/vector_style_color_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/color/vector_style_color_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/color/vector_style_color_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_meta/categorical_field_meta_popover.tsx b/x-pack/plugins/maps/public/layers/styles/vector/components/field_meta/categorical_field_meta_popover.tsx similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_meta/categorical_field_meta_popover.tsx rename to x-pack/plugins/maps/public/layers/styles/vector/components/field_meta/categorical_field_meta_popover.tsx diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_meta/field_meta_popover.tsx b/x-pack/plugins/maps/public/layers/styles/vector/components/field_meta/field_meta_popover.tsx similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_meta/field_meta_popover.tsx rename to x-pack/plugins/maps/public/layers/styles/vector/components/field_meta/field_meta_popover.tsx diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_meta/ordinal_field_meta_popover.tsx b/x-pack/plugins/maps/public/layers/styles/vector/components/field_meta/ordinal_field_meta_popover.tsx similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_meta/ordinal_field_meta_popover.tsx rename to x-pack/plugins/maps/public/layers/styles/vector/components/field_meta/ordinal_field_meta_popover.tsx diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/field_select.js similarity index 97% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_select.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/field_select.js index 2f5de507657a5..ed2e7a4eab7ec 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/field_select.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/field_select.js @@ -10,7 +10,7 @@ import React from 'react'; import { EuiComboBox, EuiHighlight, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { FIELD_ORIGIN } from '../../../../../common/constants'; import { i18n } from '@kbn/i18n'; -import { FieldIcon } from '../../../../../../../../../src/plugins/kibana_react/public'; +import { FieldIcon } from '../../../../../../../../src/plugins/kibana_react/public'; function renderOption(option, searchValue, contentClassName) { return ( diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/get_vector_style_label.js b/x-pack/plugins/maps/public/layers/styles/vector/components/get_vector_style_label.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/get_vector_style_label.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/get_vector_style_label.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/label/dynamic_label_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/label/dynamic_label_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/label/dynamic_label_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/label/dynamic_label_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/label/static_label_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/label/static_label_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/label/static_label_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/label/static_label_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_border_size_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_border_size_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_border_size_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_border_size_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/label/vector_style_label_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/__snapshots__/vector_icon.test.js.snap b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/__snapshots__/vector_icon.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/__snapshots__/vector_icon.test.js.snap rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/__snapshots__/vector_icon.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/category.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/category.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/category.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/category.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/circle_icon.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/circle_icon.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/circle_icon.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/circle_icon.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/extract_color_from_style_property.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/extract_color_from_style_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/extract_color_from_style_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/extract_color_from_style_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/line_icon.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/line_icon.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/line_icon.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/line_icon.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/polygon_icon.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/polygon_icon.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/polygon_icon.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/polygon_icon.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/symbol_icon.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/symbol_icon.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/symbol_icon.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/symbol_icon.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.test.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.test.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/vector_icon.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/vector_style_legend.js b/x-pack/plugins/maps/public/layers/styles/vector/components/legend/vector_style_legend.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/legend/vector_style_legend.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/legend/vector_style_legend.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/orientation/dynamic_orientation_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/orientation/dynamic_orientation_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/orientation/dynamic_orientation_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/orientation/dynamic_orientation_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/orientation/orientation_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/orientation/orientation_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/orientation/orientation_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/orientation/orientation_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/orientation/static_orientation_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/orientation/static_orientation_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/orientation/static_orientation_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/orientation/static_orientation_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/dynamic_size_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/size/dynamic_size_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/dynamic_size_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/size/dynamic_size_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js b/x-pack/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js similarity index 92% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js index 5de7b462136e1..ec847e2a5384e 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js @@ -6,7 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { ValidatedDualRange } from '../../../../../../../../../../src/plugins/kibana_react/public'; +import { ValidatedDualRange } from '../../../../../../../../../src/plugins/kibana_react/public'; import { MIN_SIZE, MAX_SIZE } from '../../vector_style_defaults'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/static_size_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/size/static_size_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/static_size_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/size/static_size_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/vector_style_size_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/size/vector_style_size_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/vector_style_size_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/size/vector_style_size_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/stop_input.js b/x-pack/plugins/maps/public/layers/styles/vector/components/stop_input.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/stop_input.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/stop_input.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/style_map_select.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_map_select.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/style_map_select.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_option_shapes.js b/x-pack/plugins/maps/public/layers/styles/vector/components/style_option_shapes.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_option_shapes.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/style_option_shapes.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/__snapshots__/icon_select.test.js.snap b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/__snapshots__/icon_select.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/__snapshots__/icon_select.test.js.snap rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/__snapshots__/icon_select.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/_icon_select.scss b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/_icon_select.scss similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/_icon_select.scss rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/_icon_select.scss diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/dynamic_icon_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/dynamic_icon_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/dynamic_icon_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/dynamic_icon_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_map_select.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.test.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.test.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_select.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.test.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.test.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/icon_stops.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/static_icon_form.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/static_icon_form.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/static_icon_form.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/static_icon_form.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_icon_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_icon_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_icon_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_icon_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_symbolize_as_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_symbolize_as_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_symbolize_as_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/symbol/vector_style_symbolize_as_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/vector_style_editor.js b/x-pack/plugins/maps/public/layers/styles/vector/components/vector_style_editor.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/components/vector_style_editor.js rename to x-pack/plugins/maps/public/layers/styles/vector/components/vector_style_editor.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/__snapshots__/dynamic_color_property.test.js.snap b/x-pack/plugins/maps/public/layers/styles/vector/properties/__snapshots__/dynamic_color_property.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/__snapshots__/dynamic_color_property.test.js.snap rename to x-pack/plugins/maps/public/layers/styles/vector/properties/__snapshots__/dynamic_color_property.test.js.snap diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/components/categorical_legend.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/components/categorical_legend.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/components/categorical_legend.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/components/categorical_legend.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/components/ordinal_legend.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/components/ordinal_legend.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/components/ordinal_legend.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/components/ordinal_legend.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.test.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.test.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_icon_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_icon_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_icon_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_icon_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_orientation_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts rename to x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_text_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/label_border_size_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/label_border_size_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/label_border_size_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/label_border_size_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_color_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/static_color_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_color_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/static_color_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_icon_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/static_icon_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_icon_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/static_icon_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_orientation_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/static_orientation_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_orientation_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/static_orientation_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_size_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/static_size_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_size_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/static_size_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_style_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/static_style_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_style_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/static_style_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_text_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/static_text_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/static_text_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/static_text_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/style_property.ts b/x-pack/plugins/maps/public/layers/styles/vector/properties/style_property.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/style_property.ts rename to x-pack/plugins/maps/public/layers/styles/vector/properties/style_property.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/symbolize_as_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/symbolize_as_property.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/symbolize_as_property.js rename to x-pack/plugins/maps/public/layers/styles/vector/properties/symbolize_as_property.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/style_meta.ts b/x-pack/plugins/maps/public/layers/styles/vector/style_meta.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/style_meta.ts rename to x-pack/plugins/maps/public/layers/styles/vector/style_meta.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/style_util.js b/x-pack/plugins/maps/public/layers/styles/vector/style_util.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/style_util.js rename to x-pack/plugins/maps/public/layers/styles/vector/style_util.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/style_util.test.js b/x-pack/plugins/maps/public/layers/styles/vector/style_util.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/style_util.test.js rename to x-pack/plugins/maps/public/layers/styles/vector/style_util.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/symbol_utils.js b/x-pack/plugins/maps/public/layers/styles/vector/symbol_utils.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/symbol_utils.js rename to x-pack/plugins/maps/public/layers/styles/vector/symbol_utils.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/symbol_utils.test.js b/x-pack/plugins/maps/public/layers/styles/vector/symbol_utils.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/symbol_utils.test.js rename to x-pack/plugins/maps/public/layers/styles/vector/symbol_utils.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.d.ts b/x-pack/plugins/maps/public/layers/styles/vector/vector_style.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.d.ts rename to x-pack/plugins/maps/public/layers/styles/vector/vector_style.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js b/x-pack/plugins/maps/public/layers/styles/vector/vector_style.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js rename to x-pack/plugins/maps/public/layers/styles/vector/vector_style.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.test.js b/x-pack/plugins/maps/public/layers/styles/vector/vector_style.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.test.js rename to x-pack/plugins/maps/public/layers/styles/vector/vector_style.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style_defaults.ts b/x-pack/plugins/maps/public/layers/styles/vector/vector_style_defaults.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style_defaults.ts rename to x-pack/plugins/maps/public/layers/styles/vector/vector_style_defaults.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/tile_layer.d.ts b/x-pack/plugins/maps/public/layers/tile_layer.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/tile_layer.d.ts rename to x-pack/plugins/maps/public/layers/tile_layer.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/tile_layer.js b/x-pack/plugins/maps/public/layers/tile_layer.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/tile_layer.js rename to x-pack/plugins/maps/public/layers/tile_layer.js diff --git a/x-pack/legacy/plugins/maps/public/layers/tile_layer.test.ts b/x-pack/plugins/maps/public/layers/tile_layer.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/tile_layer.test.ts rename to x-pack/plugins/maps/public/layers/tile_layer.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts b/x-pack/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts rename to x-pack/plugins/maps/public/layers/tooltips/es_agg_tooltip_property.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/tooltips/es_tooltip_property.ts b/x-pack/plugins/maps/public/layers/tooltips/es_tooltip_property.ts similarity index 95% rename from x-pack/legacy/plugins/maps/public/layers/tooltips/es_tooltip_property.ts rename to x-pack/plugins/maps/public/layers/tooltips/es_tooltip_property.ts index 8fd7e173435ce..5c35009881920 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tooltips/es_tooltip_property.ts +++ b/x-pack/plugins/maps/public/layers/tooltips/es_tooltip_property.ts @@ -7,8 +7,8 @@ import _ from 'lodash'; import { ITooltipProperty } from './tooltip_property'; import { IField } from '../fields/field'; -import { esFilters, IFieldType, IndexPattern } from '../../../../../../../src/plugins/data/public'; -import { PhraseFilter } from '../../../../../../../src/plugins/data/public'; +import { esFilters, IFieldType, IndexPattern } from '../../../../../../src/plugins/data/public'; +import { PhraseFilter } from '../../../../../../src/plugins/data/public'; export class ESTooltipProperty implements ITooltipProperty { private readonly _tooltipProperty: ITooltipProperty; diff --git a/x-pack/legacy/plugins/maps/public/layers/tooltips/join_tooltip_property.ts b/x-pack/plugins/maps/public/layers/tooltips/join_tooltip_property.ts similarity index 96% rename from x-pack/legacy/plugins/maps/public/layers/tooltips/join_tooltip_property.ts rename to x-pack/plugins/maps/public/layers/tooltips/join_tooltip_property.ts index 02f0920ce3c61..4af236f6e9e36 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tooltips/join_tooltip_property.ts +++ b/x-pack/plugins/maps/public/layers/tooltips/join_tooltip_property.ts @@ -6,7 +6,7 @@ import { ITooltipProperty } from './tooltip_property'; import { IJoin } from '../joins/join'; -import { PhraseFilter } from '../../../../../../../src/plugins/data/public'; +import { PhraseFilter } from '../../../../../../src/plugins/data/public'; export class JoinTooltipProperty implements ITooltipProperty { private readonly _tooltipProperty: ITooltipProperty; diff --git a/x-pack/legacy/plugins/maps/public/layers/tooltips/tooltip_property.ts b/x-pack/plugins/maps/public/layers/tooltips/tooltip_property.ts similarity index 92% rename from x-pack/legacy/plugins/maps/public/layers/tooltips/tooltip_property.ts rename to x-pack/plugins/maps/public/layers/tooltips/tooltip_property.ts index 46e27bbd770a1..7d680dfe9cae0 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tooltips/tooltip_property.ts +++ b/x-pack/plugins/maps/public/layers/tooltips/tooltip_property.ts @@ -5,8 +5,8 @@ */ import _ from 'lodash'; -import { PhraseFilter } from '../../../../../../../src/plugins/data/public'; -import { TooltipFeature } from '../../../../../../plugins/maps/common/descriptor_types'; +import { PhraseFilter } from '../../../../../../src/plugins/data/public'; +import { TooltipFeature } from '../../../../../plugins/maps/common/descriptor_types'; export interface ITooltipProperty { getPropertyKey(): string; diff --git a/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.test.ts b/x-pack/plugins/maps/public/layers/util/assign_feature_ids.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.test.ts rename to x-pack/plugins/maps/public/layers/util/assign_feature_ids.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.ts b/x-pack/plugins/maps/public/layers/util/assign_feature_ids.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.ts rename to x-pack/plugins/maps/public/layers/util/assign_feature_ids.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.test.js b/x-pack/plugins/maps/public/layers/util/can_skip_fetch.test.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.test.js rename to x-pack/plugins/maps/public/layers/util/can_skip_fetch.test.js diff --git a/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.ts b/x-pack/plugins/maps/public/layers/util/can_skip_fetch.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.ts rename to x-pack/plugins/maps/public/layers/util/can_skip_fetch.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/util/data_request.ts b/x-pack/plugins/maps/public/layers/util/data_request.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/data_request.ts rename to x-pack/plugins/maps/public/layers/util/data_request.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.test.ts b/x-pack/plugins/maps/public/layers/util/es_agg_utils.test.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.test.ts rename to x-pack/plugins/maps/public/layers/util/es_agg_utils.test.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.ts b/x-pack/plugins/maps/public/layers/util/es_agg_utils.ts similarity index 95% rename from x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.ts rename to x-pack/plugins/maps/public/layers/util/es_agg_utils.ts index 9d4f24f80d6cd..329a2a6fc64fb 100644 --- a/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.ts +++ b/x-pack/plugins/maps/public/layers/util/es_agg_utils.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; import _ from 'lodash'; -import { IndexPattern, IFieldType } from '../../../../../../../src/plugins/data/public'; +import { IndexPattern, IFieldType } from '../../../../../../src/plugins/data/public'; import { TOP_TERM_PERCENTAGE_SUFFIX } from '../../../common/constants'; export function getField(indexPattern: IndexPattern, fieldName: string) { diff --git a/x-pack/legacy/plugins/maps/public/layers/util/is_metric_countable.ts b/x-pack/plugins/maps/public/layers/util/is_metric_countable.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/is_metric_countable.ts rename to x-pack/plugins/maps/public/layers/util/is_metric_countable.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/util/is_refresh_only_query.ts b/x-pack/plugins/maps/public/layers/util/is_refresh_only_query.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/is_refresh_only_query.ts rename to x-pack/plugins/maps/public/layers/util/is_refresh_only_query.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/util/mb_filter_expressions.ts b/x-pack/plugins/maps/public/layers/util/mb_filter_expressions.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/util/mb_filter_expressions.ts rename to x-pack/plugins/maps/public/layers/util/mb_filter_expressions.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.d.ts b/x-pack/plugins/maps/public/layers/vector_layer.d.ts similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/vector_layer.d.ts rename to x-pack/plugins/maps/public/layers/vector_layer.d.ts diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js b/x-pack/plugins/maps/public/layers/vector_layer.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/vector_layer.js rename to x-pack/plugins/maps/public/layers/vector_layer.js diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_tile_layer.js b/x-pack/plugins/maps/public/layers/vector_tile_layer.js similarity index 100% rename from x-pack/legacy/plugins/maps/public/layers/vector_tile_layer.js rename to x-pack/plugins/maps/public/layers/vector_tile_layer.js diff --git a/x-pack/legacy/plugins/maps/public/meta.js b/x-pack/plugins/maps/public/meta.js similarity index 76% rename from x-pack/legacy/plugins/maps/public/meta.js rename to x-pack/plugins/maps/public/meta.js index 4d81785ff7a0a..d4612554cf00b 100644 --- a/x-pack/legacy/plugins/maps/public/meta.js +++ b/x-pack/plugins/maps/public/meta.js @@ -11,20 +11,19 @@ import { EMS_GLYPHS_PATH, EMS_APP_NAME, } from '../common/constants'; -import chrome from 'ui/chrome'; import { i18n } from '@kbn/i18n'; import { EMSClient } from '@elastic/ems-client'; -import { getLicenseId } from './kibana_services'; +import { getInjectedVarFunc, getLicenseId } from './kibana_services'; import fetch from 'node-fetch'; const GIS_API_RELATIVE = `../${GIS_API_PATH}`; export function getKibanaRegionList() { - return chrome.getInjected('regionmapLayers'); + return getInjectedVarFunc()('regionmapLayers'); } export function getKibanaTileMap() { - return chrome.getInjected('tilemap'); + return getInjectedVarFunc()('tilemap'); } function relativeToAbsolute(url) { @@ -41,27 +40,27 @@ let emsClient = null; let latestLicenseId = null; export function getEMSClient() { if (!emsClient) { - const isEmsEnabled = chrome.getInjected('isEmsEnabled', true); + const isEmsEnabled = getInjectedVarFunc()('isEmsEnabled', true); if (isEmsEnabled) { - const proxyElasticMapsServiceInMaps = chrome.getInjected( + const proxyElasticMapsServiceInMaps = getInjectedVarFunc()( 'proxyElasticMapsServiceInMaps', false ); const proxyPath = ''; const tileApiUrl = proxyElasticMapsServiceInMaps ? relativeToAbsolute(`${GIS_API_RELATIVE}/${EMS_TILES_CATALOGUE_PATH}`) - : chrome.getInjected('emsTileApiUrl'); + : getInjectedVarFunc()('emsTileApiUrl'); const fileApiUrl = proxyElasticMapsServiceInMaps ? relativeToAbsolute(`${GIS_API_RELATIVE}/${EMS_FILES_CATALOGUE_PATH}`) - : chrome.getInjected('emsFileApiUrl'); + : getInjectedVarFunc()('emsFileApiUrl'); emsClient = new EMSClient({ language: i18n.getLocale(), - appVersion: chrome.getInjected('kbnPkgVersion'), + appVersion: getInjectedVarFunc()('kbnPkgVersion'), appName: EMS_APP_NAME, tileApiUrl, fileApiUrl, - landingPageUrl: chrome.getInjected('emsLandingPageUrl'), + landingPageUrl: getInjectedVarFunc()('emsLandingPageUrl'), fetchFunction: fetchFunction, //import this from client-side, so the right instance is returned (bootstrapped from common/* would not work proxyPath, }); @@ -87,13 +86,13 @@ export function getEMSClient() { } export function getGlyphUrl() { - if (!chrome.getInjected('isEmsEnabled', true)) { + if (!getInjectedVarFunc()('isEmsEnabled', true)) { return ''; } - return chrome.getInjected('proxyElasticMapsServiceInMaps', false) + return getInjectedVarFunc()('proxyElasticMapsServiceInMaps', false) ? relativeToAbsolute(`../${GIS_API_PATH}/${EMS_TILES_CATALOGUE_PATH}/${EMS_GLYPHS_PATH}`) + `/{fontstack}/{range}` - : chrome.getInjected('emsFontLibraryUrl', true); + : getInjectedVarFunc()('emsFontLibraryUrl', true); } export function isRetina() { diff --git a/x-pack/legacy/plugins/maps/public/meta.test.js b/x-pack/plugins/maps/public/meta.test.js similarity index 57% rename from x-pack/legacy/plugins/maps/public/meta.test.js rename to x-pack/plugins/maps/public/meta.test.js index 64dd73fe109ff..d83f2adb35ef7 100644 --- a/x-pack/legacy/plugins/maps/public/meta.test.js +++ b/x-pack/plugins/maps/public/meta.test.js @@ -9,39 +9,24 @@ import { getEMSClient } from './meta'; jest.mock('@elastic/ems-client'); -jest.mock('ui/chrome', () => ({ - getBasePath: () => { - return ''; - }, - getInjected(key) { - if (key === 'proxyElasticMapsServiceInMaps') { - return false; - } else if (key === 'isEmsEnabled') { - return true; - } else if (key === 'emsFileApiUrl') { - return 'https://file-api'; - } else if (key === 'emsTileApiUrl') { - return 'https://tile-api'; - } - }, - getUiSettingsClient: () => { - return { - get: () => { - return ''; - }, +describe('default use without proxy', () => { + beforeEach(() => { + require('./kibana_services').getInjectedVarFunc = () => key => { + if (key === 'proxyElasticMapsServiceInMaps') { + return false; + } else if (key === 'isEmsEnabled') { + return true; + } else if (key === 'emsFileApiUrl') { + return 'https://file-api'; + } else if (key === 'emsTileApiUrl') { + return 'https://tile-api'; + } }; - }, -})); - -jest.mock('./kibana_services', () => { - return { - getLicenseId() { + require('./kibana_services').getLicenseId = () => { return 'foobarlicenseid'; - }, - }; -}); + }; + }); -describe('default use without proxy', () => { it('should construct EMSClient with absolute file and tile API urls', async () => { getEMSClient(); const mockEmsClientCall = EMSClient.mock.calls[0]; diff --git a/x-pack/plugins/maps/public/plugin.ts b/x-pack/plugins/maps/public/plugin.ts index 506b0c426f0fa..9437c2512ded4 100644 --- a/x-pack/plugins/maps/public/plugin.ts +++ b/x-pack/plugins/maps/public/plugin.ts @@ -8,6 +8,20 @@ import { Plugin, CoreSetup, CoreStart } from 'src/core/public'; import { Setup as InspectorSetupContract } from 'src/plugins/inspector/public'; // @ts-ignore import { MapView } from './inspector/views/map_view'; +import { + setAutocompleteService, + setFileUpload, + setHttp, + setIndexPatternSelect, + setIndexPatternService, + setInjectedVarFunc, + setInspector, + setLicenseId, + setTimeFilter, + setToasts, + setUiSettings, + // @ts-ignore +} from './kibana_services'; export interface MapsPluginSetupDependencies { inspector: InspectorSetupContract; @@ -15,6 +29,29 @@ export interface MapsPluginSetupDependencies { // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface MapsPluginStartDependencies {} +export const bindSetupCoreAndPlugins = (core: CoreSetup, plugins: any) => { + const { licensing } = plugins; + const { injectedMetadata, http } = core; + if (licensing) { + licensing.license$.subscribe(({ uid }: { uid: string }) => setLicenseId(uid)); + } + setInjectedVarFunc(injectedMetadata.getInjectedVar); + setHttp(http); + setUiSettings(core.uiSettings); + setInjectedVarFunc(core.injectedMetadata.getInjectedVar); + setToasts(core.notifications.toasts); +}; + +export const bindStartCoreAndPlugins = (core: CoreStart, plugins: any) => { + const { file_upload, data, inspector } = plugins; + setInspector(inspector); + setFileUpload(file_upload); + setIndexPatternSelect(data.ui.IndexPatternSelect); + setTimeFilter(data.query.timefilter.timefilter); + setIndexPatternService(data.indexPatterns); + setAutocompleteService(data.autocomplete); +}; + /** * These are the interfaces with your public contracts. You should export these * for other plugins to use in _their_ `SetupDeps`/`StartDeps` interfaces. From 809ec9764929aca307e769c4fc31a8941cd33fef Mon Sep 17 00:00:00 2001 From: Kaarina Tungseth Date: Mon, 6 Apr 2020 15:37:45 -0500 Subject: [PATCH 7/8] [DOCS] Removed references to left (#60807) * [DOCS] Removed references to left * Fixed broken build --- docs/apm/transactions.asciidoc | 4 +--- docs/canvas/canvas-elements.asciidoc | 4 +++- docs/canvas/canvas-present-workpad.asciidoc | 4 ++-- docs/canvas/canvas-share-workpad.asciidoc | 8 ++++---- .../searchprofiler/getting-started.asciidoc | 12 ++++++------ docs/discover/document-data.asciidoc | 2 +- docs/getting-started/tutorial-visualizing.asciidoc | 2 +- docs/infrastructure/view-metrics.asciidoc | 8 -------- docs/management/managing-licenses.asciidoc | 3 +-- docs/spaces/index.asciidoc | 4 ++-- docs/user/dashboard.asciidoc | 2 +- docs/user/discover.asciidoc | 4 ++-- docs/visualize/lens.asciidoc | 12 ++++-------- 13 files changed, 28 insertions(+), 41 deletions(-) diff --git a/docs/apm/transactions.asciidoc b/docs/apm/transactions.asciidoc index 536ab2ec29c80..5c92afa55109d 100644 --- a/docs/apm/transactions.asciidoc +++ b/docs/apm/transactions.asciidoc @@ -103,9 +103,7 @@ The number of requests per bucket is displayed when hovering over the graph, and [role="screenshot"] image::apm/images/apm-transaction-duration-dist.png[Example view of transactions duration distribution graph] -Most of the requests fall into buckets on the left side of the graph, -with a long tail of smaller buckets to the right. -This is a typical distribution, and indicates most of our requests were served quickly - awesome! +This graph shows a typical distribution, and indicates most of our requests were served quickly - awesome! It's the requests on the right, the ones taking longer than average, that we probably want to focus on. When you select one of these buckets, you're presented with up to ten trace samples. diff --git a/docs/canvas/canvas-elements.asciidoc b/docs/canvas/canvas-elements.asciidoc index 163579d5763b2..a25460a20eb50 100644 --- a/docs/canvas/canvas-elements.asciidoc +++ b/docs/canvas/canvas-elements.asciidoc @@ -138,7 +138,9 @@ To apply CSS overrides: . Next to *Element style*, click *+*, then select *CSS*. -. Enter the *CSS*. For example, to center the Markdown element, enter: +. Enter the *CSS*. ++ +For example, to center the Markdown element, enter: + [source,text] -------------------------------------------------- diff --git a/docs/canvas/canvas-present-workpad.asciidoc b/docs/canvas/canvas-present-workpad.asciidoc index 486686cd857b5..9cd4ecc9519e1 100644 --- a/docs/canvas/canvas-present-workpad.asciidoc +++ b/docs/canvas/canvas-present-workpad.asciidoc @@ -8,7 +8,7 @@ When you are ready to present your workpad, use and enable the presentation opti [[view-fullscreen-mode]] ==== View your workpad in fullscreen mode -In the upper left corner, click the *Enter fullscreen mode* icon. +Click the *Enter fullscreen mode* icon. [role="screenshot"] image::images/canvas-fullscreen.png[Fullscreen mode] @@ -19,7 +19,7 @@ image::images/canvas-fullscreen.png[Fullscreen mode] Automatically cycle through your workpads pages in fullscreen mode. -. In the upper left corner, click the *Control settings* icon. +. Click the *Control settings* icon. . Under *Change cycling interval*, select the interval you want to use. + diff --git a/docs/canvas/canvas-share-workpad.asciidoc b/docs/canvas/canvas-share-workpad.asciidoc index dbba12865b8ca..ee29926914ad6 100644 --- a/docs/canvas/canvas-share-workpad.asciidoc +++ b/docs/canvas/canvas-share-workpad.asciidoc @@ -10,7 +10,7 @@ When you've finished your workpad, you can share it outside of {kib}. Create a JSON file of your workpad that you can export outside of {kib}. -. From your workpad, click the *Share workpad* icon in the upper left corner. +. From your workpad, click the *Share workpad* icon. . Select *Download as JSON*. + @@ -27,7 +27,7 @@ If you have a license that supports the {report-features}, you can create a PDF For more information, refer to <>. -. From your workpad, click the *Share workpad* icon in the upper left corner, then select *PDF reports*. +. From your workpad, click the *Share workpad* icon, then select *PDF reports*. . Click *Generate PDF*. + @@ -42,7 +42,7 @@ If you have a license that supports the {report-features}, you can create a POST For more information, refer to <>. -. From your workpad, click the *Share workpad* icon in the upper left corner, then select *PDF reports*. +. From your workpad, click the *Share workpad* icon, then select *PDF reports*. . Click *Copy POST URL*. + @@ -55,7 +55,7 @@ image::images/canvas-create-URL.gif[Create POST URL] beta[] Canvas allows you to create _shareables_, which are workpads that you download and securely share on any website. To customize the behavior of the workpad on your website, you can choose to autoplay the pages or hide the workpad toolbar. -. From your workpad, click the *Share this workpad* icon in the upper left corner, then select *Share on a website*. +. From your workpad, click the *Share this workpad* icon, then select *Share on a website*. . On the *Share on a website* pane, follow the instructions. diff --git a/docs/dev-tools/searchprofiler/getting-started.asciidoc b/docs/dev-tools/searchprofiler/getting-started.asciidoc index 2360e4c28ff15..4a87d4b84b783 100644 --- a/docs/dev-tools/searchprofiler/getting-started.asciidoc +++ b/docs/dev-tools/searchprofiler/getting-started.asciidoc @@ -3,10 +3,10 @@ === Getting Started The {searchprofiler} is automatically enabled in {kib}. Go to *Dev Tools > Search Profiler* -to get started. +to get started. {searchprofiler} displays the names of the indices searched, the shards in each index, -and how long it took for the query to complete. To try it out, replace the default `match_all` query +and how long it took for the query to complete. To try it out, replace the default `match_all` query with the query you want to profile and click *Profile*. The following example shows the results of profiling the `match_all` query. @@ -29,8 +29,8 @@ While the Cumulative Time metric is useful for comparing the performance of your indices and shards, it doesn't necessarily represent the actual physical query times. ==== -You can select the name of the shard and then click *View details* to see more profiling information, -including details about the query component(s) that ran on the shard, as well as the timing +You can select the name of the shard and then click *View details* to see more profiling information, +including details about the query component(s) that ran on the shard, as well as the timing breakdown of low-level Lucene methods. For more information, see {ref}/search-profile.html#profiling-queries[Profiling queries]. [float] @@ -40,10 +40,10 @@ By default, all queries executed by the {searchprofiler} are sent to `GET /_search`. It searches across your entire cluster (all indices, all types). If you need to query a specific index or type (or several), you can use the Index -and Type filters at the top left. +and Type filters. In the following example, the query is executed against the indices `test` and `kibana_1` and the type `my_type`. This is equivalent making a request to `GET /test,kibana_1/my_type/_search`. [role="screenshot"] -image::dev-tools/searchprofiler/images/filter.png["Filtering by index and type"] \ No newline at end of file +image::dev-tools/searchprofiler/images/filter.png["Filtering by index and type"] diff --git a/docs/discover/document-data.asciidoc b/docs/discover/document-data.asciidoc index 6e9218d66c115..477c2ec90e95c 100644 --- a/docs/discover/document-data.asciidoc +++ b/docs/discover/document-data.asciidoc @@ -26,7 +26,7 @@ and click image:images/sort-icon.png[]. The first click sorts by ascending order, the second click sorts by descending order, and the third click removes the field from the sorted fields. -Move a field column:: Hover over the column header and click the move left (<<) or move right icon (>>). +Move a field column:: Hover over the column header and click the (<<) or (>>) icons. Remove a field column :: Hover over the list of *Specified fields* and then click *remove*. Or, use the (x) control in the column header. diff --git a/docs/getting-started/tutorial-visualizing.asciidoc b/docs/getting-started/tutorial-visualizing.asciidoc index a16343aa4850a..acd4d6d908fd4 100644 --- a/docs/getting-started/tutorial-visualizing.asciidoc +++ b/docs/getting-started/tutorial-visualizing.asciidoc @@ -180,5 +180,5 @@ The map now looks like this: image::images/tutorial-visualize-map-2.png[] . Navigate the map by clicking and dragging. Use the controls -on the left to zoom the map and set filters. +to zoom the map and set filters. . *Save* this map with the name `Map Example`. diff --git a/docs/infrastructure/view-metrics.asciidoc b/docs/infrastructure/view-metrics.asciidoc index bbb981acc3ad6..1bd64dde76ee1 100644 --- a/docs/infrastructure/view-metrics.asciidoc +++ b/docs/infrastructure/view-metrics.asciidoc @@ -30,11 +30,3 @@ For complete control over the start and end times, click the start time or end t === Refresh the metrics You can click *Refresh* to manually refresh the metrics. - -[float] -[[infra-view-go-to-chart]] -=== Go to a specific chart - -The charts available for this component are shown in a list on the left of the page. Click a chart in the list to quickly go to that chart. - - diff --git a/docs/management/managing-licenses.asciidoc b/docs/management/managing-licenses.asciidoc index 72accdb5fe2aa..a7ed4e942f3f6 100644 --- a/docs/management/managing-licenses.asciidoc +++ b/docs/management/managing-licenses.asciidoc @@ -15,8 +15,7 @@ already activated a trial for 6.0, you cannot start a new trial until 7.0. You can, however, contact `info@elastic.co` to request an extended trial license. -When you activate a new license level, new features appear in the left sidebar -of the *Management* page. +When you activate a new license level, new features appear in *Management*. [role="screenshot"] image::images/management-license.png[] diff --git a/docs/spaces/index.asciidoc b/docs/spaces/index.asciidoc index fb5ef670692dc..990af3a018b1f 100644 --- a/docs/spaces/index.asciidoc +++ b/docs/spaces/index.asciidoc @@ -9,10 +9,10 @@ the dashboards and saved objects that belong to that space. {kib} creates a default space for you. After you create your own spaces, you're asked to choose a space when you log in to Kibana. You can change your -current space at any time by using the menu in the upper left. +current space at any time by using the menu. [role="screenshot"] -image::spaces/images/change-space.png["Change current space"] +image::spaces/images/change-space.png["Change current space menu"] Kibana supports spaces in several ways. You can: diff --git a/docs/user/dashboard.asciidoc b/docs/user/dashboard.asciidoc index 490edb9d26338..a17e46c5b3542 100644 --- a/docs/user/dashboard.asciidoc +++ b/docs/user/dashboard.asciidoc @@ -93,7 +93,7 @@ In *Edit* mode, you can move, resize, customize, and delete panels to suit your * To resize a panel, click the resize control on the lower right and drag to the new dimensions. -* To toggle the use of margins and panel titles, use the *Options* menu in the upper left. +* To toggle the use of margins and panel titles, use the *Options* menu. * To delete a panel, open the panel menu and select *Delete from dashboard.* Deleting a panel from a dashboard does *not* delete the saved visualization or search. diff --git a/docs/user/discover.asciidoc b/docs/user/discover.asciidoc index 7de7d73bf1664..4222ba40debb7 100644 --- a/docs/user/discover.asciidoc +++ b/docs/user/discover.asciidoc @@ -24,7 +24,7 @@ image::images/Discover-Start.png[Discover] === Set up your index pattern The first thing to do in *Discover* is to select an <>, which -defines the data you want to explore and visualize. The current index pattern is in the upper left. +defines the data you want to explore and visualize. If you haven't yet created an index pattern, you can add a <>, which has a pre-built index pattern. @@ -69,7 +69,7 @@ image::images/filter-field.png[height=317] The sortable documents table lists the documents that match your search. By default, the table includes columns for the time field and the document `_source`. -To zero in on a specific field, click *add* next to the field name in the left sidebar. +To zero in on a specific field, click *add* next to the field name. For example, if you add the `currency`, `customer_last_name`, and `day_of_week` fields, the document table includes columns for those three fields. diff --git a/docs/visualize/lens.asciidoc b/docs/visualize/lens.asciidoc index e3f61565453b5..35570ea7ca1dc 100644 --- a/docs/visualize/lens.asciidoc +++ b/docs/visualize/lens.asciidoc @@ -32,7 +32,7 @@ Lens supports the following aggregations: [[drag-drop]] === Drag and drop -The data panel in the left column shows the data fields for the selected time period. When +The panel shows the data fields for the selected time period. When you drag a field from the data panel, Lens highlights where you can drop that field. The first time you drag a data field, you'll see two places highlighted in green: @@ -57,7 +57,7 @@ Lens shows you fields based on the <> you have d {kib}, and the current time range. When you change the index pattern or time filter, the list of fields are updated. -To narrow the list of fields you see in the left panel, you can: +To narrow the list of fields, you can: * Enter the field name in *Search field names*. @@ -100,11 +100,7 @@ still allows you to make the change. Lens allows some customizations of the data for each visualization. -. Change the index pattern. - -.. In the left column, click the index pattern name. - -.. Select the new index pattern. +. Click the index pattern name, then select the new index pattern. + If there is a match, Lens displays the new data. All fields that do not match the index pattern are removed. @@ -147,7 +143,7 @@ Drag and drop your data onto the visualization builder pane. . On the *New Visualization* window, click *Lens*. -. In the left column, select the *kibana_sample_data_ecommerce* index. +. Select the *kibana_sample_data_ecommerce* index. . Click image:images/time-filter-calendar.png[], then click *Last 7 days*. The list of data fields are updated. From e16885c3ad2b3bf6aac3ba0a9dc0548dc5020741 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Tue, 7 Apr 2020 00:36:15 +0300 Subject: [PATCH 8/8] [Telemetry] update crypto packages (#62469) * update crypto packages * as type for return value * get default export * add if checks * wrap errors in i18n Co-authored-by: Elastic Machine --- package.json | 2 +- typings/elastic__node_crypto.d.ts | 20 ---------------- .../common/execute_job/decrypt_job_headers.ts | 13 ++++++++--- .../export_types/csv/server/execute_job.ts | 14 ++++++++--- .../server/execute_job.ts | 15 +++++++++++- .../plugins/reporting/server/lib/crypto.ts | 6 ++++- x-pack/legacy/plugins/reporting/types.d.ts | 4 ---- x-pack/package.json | 2 +- .../encrypted_saved_objects_service.test.ts | 7 +++--- .../crypto/encrypted_saved_objects_service.ts | 12 ++++------ x-pack/typings/elastic__node_crypto.d.ts | 7 ------ yarn.lock | 23 ++++++++----------- 12 files changed, 59 insertions(+), 66 deletions(-) delete mode 100644 typings/elastic__node_crypto.d.ts delete mode 100644 x-pack/typings/elastic__node_crypto.d.ts diff --git a/package.json b/package.json index e807cd4d95198..4c5db5321c282 100644 --- a/package.json +++ b/package.json @@ -126,7 +126,7 @@ "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", "@elastic/numeral": "2.4.0", - "@elastic/request-crypto": "^1.0.2", + "@elastic/request-crypto": "1.1.2", "@elastic/ui-ace": "0.2.3", "@hapi/good-squeeze": "5.2.1", "@hapi/wreck": "^15.0.2", diff --git a/typings/elastic__node_crypto.d.ts b/typings/elastic__node_crypto.d.ts deleted file mode 100644 index 8d4b47da96b73..0000000000000 --- a/typings/elastic__node_crypto.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -declare module '@elastic/node-crypto'; diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts index 6f415d7ee5ea9..0436f5d5bc843 100644 --- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts +++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; import { cryptoFactory } from '../../../server/lib/crypto'; -import { CryptoFactory, Logger } from '../../../types'; +import { Logger } from '../../../types'; interface HasEncryptedHeaders { headers?: string; @@ -25,9 +25,16 @@ export const decryptJobHeaders = async < job: JobDocPayloadType; logger: Logger; }): Promise> => { - const crypto: CryptoFactory = cryptoFactory(encryptionKey); try { - const decryptedHeaders: Record = await crypto.decrypt(job.headers); + if (typeof job.headers !== 'string') { + throw new Error( + i18n.translate('xpack.reporting.exportTypes.common.missingJobHeadersErrorMessage', { + defaultMessage: 'Job headers are missing', + }) + ); + } + const crypto = cryptoFactory(encryptionKey); + const decryptedHeaders = (await crypto.decrypt(job.headers)) as Record; return decryptedHeaders; } catch (err) { logger.error(err); diff --git a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts index d78d8a8a8010d..3a282eb0b2974 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv/server/execute_job.ts @@ -43,9 +43,18 @@ export const executeJobFactory: ExecuteJobFactory { - let decryptedHeaders; try { - decryptedHeaders = await crypto.decrypt(headers); + if (typeof headers !== 'string') { + throw new Error( + i18n.translate( + 'xpack.reporting.exportTypes.csv.executeJob.missingJobHeadersErrorMessage', + { + defaultMessage: 'Job headers are missing', + } + ) + ); + } + return await crypto.decrypt(headers); } catch (err) { logger.error(err); throw new Error( @@ -58,7 +67,6 @@ export const executeJobFactory: ExecuteJobFactory; const serializedEncryptedHeaders = job.headers; try { - decryptedHeaders = await crypto.decrypt(serializedEncryptedHeaders); + if (typeof serializedEncryptedHeaders !== 'string') { + throw new Error( + i18n.translate( + 'xpack.reporting.exportTypes.csv_from_savedobject.executeJob.missingJobHeadersErrorMessage', + { + defaultMessage: 'Job headers are missing', + } + ) + ); + } + decryptedHeaders = (await crypto.decrypt(serializedEncryptedHeaders)) as Record< + string, + unknown + >; } catch (err) { jobLogger.error(err); throw new Error( diff --git a/x-pack/legacy/plugins/reporting/server/lib/crypto.ts b/x-pack/legacy/plugins/reporting/server/lib/crypto.ts index 97876529ecfa7..0394c8ed1fbad 100644 --- a/x-pack/legacy/plugins/reporting/server/lib/crypto.ts +++ b/x-pack/legacy/plugins/reporting/server/lib/crypto.ts @@ -6,6 +6,10 @@ import nodeCrypto from '@elastic/node-crypto'; -export function cryptoFactory(encryptionKey: string | undefined) { +export function cryptoFactory(encryptionKey?: string) { + if (typeof encryptionKey !== 'string') { + throw new Error('Encryption Key required.'); + } + return nodeCrypto({ encryptionKey }); } diff --git a/x-pack/legacy/plugins/reporting/types.d.ts b/x-pack/legacy/plugins/reporting/types.d.ts index 09d53278941c9..7334a859005e0 100644 --- a/x-pack/legacy/plugins/reporting/types.d.ts +++ b/x-pack/legacy/plugins/reporting/types.d.ts @@ -116,10 +116,6 @@ export interface ConditionalHeadersConditions { basePath: string; } -export interface CryptoFactory { - decrypt: (headers?: string) => any; -} - export interface IndexPatternSavedObject { attributes: { fieldFormatMap: string; diff --git a/x-pack/package.json b/x-pack/package.json index 24b23256bf18e..b2ec4c3dc3f6f 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -185,7 +185,7 @@ "@elastic/eui": "21.0.1", "@elastic/filesaver": "1.1.2", "@elastic/maki": "6.2.0", - "@elastic/node-crypto": "^1.0.0", + "@elastic/node-crypto": "1.1.1", "@elastic/numeral": "2.4.0", "@kbn/babel-preset": "1.0.0", "@kbn/config-schema": "1.0.0", diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts index e1e1a8224aa7b..be33238a26ee7 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts @@ -19,9 +19,10 @@ beforeEach(() => { mockAuditLogger = encryptedSavedObjectsAuditLoggerMock.create(); // Call actual `@elastic/node-crypto` by default, but allow to override implementation in tests. - jest - .requireMock('@elastic/node-crypto') - .mockImplementation((...args: any[]) => jest.requireActual('@elastic/node-crypto')(...args)); + jest.requireMock('@elastic/node-crypto').mockImplementation((...args: any[]) => { + const { default: nodeCrypto } = jest.requireActual('@elastic/node-crypto'); + return nodeCrypto(...args); + }); service = new EncryptedSavedObjectsService( 'encryption-key-abc', diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts index 94c1684529577..eea2b12354d9b 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore -import nodeCrypto from '@elastic/node-crypto'; +import nodeCrypto, { Crypto } from '@elastic/node-crypto'; import stringify from 'json-stable-stringify'; import typeDetect from 'type-detect'; import { Logger } from 'src/core/server'; @@ -49,10 +48,7 @@ export function descriptorToArray(descriptor: SavedObjectDescriptor) { * attributes. */ export class EncryptedSavedObjectsService { - private readonly crypto: Readonly<{ - encrypt(valueToEncrypt: T, aad?: string): Promise; - decrypt(valueToDecrypt: string, aad?: string): Promise; - }>; + private readonly crypto: Readonly; /** * Map of all registered saved object types where the `key` is saved object type and the `value` @@ -229,10 +225,10 @@ export class EncryptedSavedObjectsService { } try { - decryptedAttributes[attributeName] = await this.crypto.decrypt( + decryptedAttributes[attributeName] = (await this.crypto.decrypt( attributeValue, encryptionAAD - ); + )) as string; } catch (err) { this.logger.error(`Failed to decrypt "${attributeName}" attribute: ${err.message || err}`); this.audit.decryptAttributeFailure(attributeName, descriptor); diff --git a/x-pack/typings/elastic__node_crypto.d.ts b/x-pack/typings/elastic__node_crypto.d.ts deleted file mode 100644 index 463b662d5b207..0000000000000 --- a/x-pack/typings/elastic__node_crypto.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -declare module '@elastic/node-crypto'; diff --git a/yarn.lock b/yarn.lock index d9edb55a32039..77ab69c715573 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1343,27 +1343,22 @@ resolved "https://registry.yarnpkg.com/@elastic/maki/-/maki-6.2.0.tgz#d0a85aa248bdc14dca44e1f9430c0b670f65e489" integrity sha512-QkmRNpEY4Dy6eqwDimR5X9leMgdPFjdANmpEIwEW1XVUG2U4YtB2BXhDxsnMmNTUrJUjtnjnwgwBUyg0pU0FTg== -"@elastic/node-crypto@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@elastic/node-crypto/-/node-crypto-0.1.2.tgz#c18ac282f635e88f041cc1555d806e492ca8f3b1" - integrity sha1-wYrCgvY16I8EHMFVXYBuSSyo87E= - -"@elastic/node-crypto@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@elastic/node-crypto/-/node-crypto-1.0.0.tgz#4d325df333fe1319556bb4d54214098ada1171d4" - integrity sha512-bbjbEyILPRTRt0xnda18OttLtlkJBPuXx3CjISUSn9jhWqHoFMzfOaZ73D5jxZE2SaFZUrJYfPpqXP6qqPufAQ== +"@elastic/node-crypto@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@elastic/node-crypto/-/node-crypto-1.1.1.tgz#619b70322c9cce4a7ee5fbf8f678b1baa7f06095" + integrity sha512-F6tIk8Txdqjg8Siv60iAvXzO9ZdQI87K3sS/fh5xd2XaWK+T5ZfqeTvsT7srwG6fr6uCBfuQEJV1KBBl+JpLZA== "@elastic/numeral@2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@elastic/numeral/-/numeral-2.4.0.tgz#883197b7f4bf3c2dd994f53b274769ddfa2bf79a" integrity sha512-uGBKGCNghTgUZPHClji/00v+AKt5nidPTGOIbcT+lbTPVxNB6QPpPLGWtXyrg3QZAxobPM/LAZB1mAqtJeq44Q== -"@elastic/request-crypto@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@elastic/request-crypto/-/request-crypto-1.0.2.tgz#bf27bf009227166f3eeb2b5193a108752335ebd3" - integrity sha512-8FtGYl7LebhmJmEDWiGn3MorvNiGWSYPqhvgRlKXjNakEuLoPBBe0DHxbwLkj08CMLWczXcO2ixqBPY7fEhJpA== +"@elastic/request-crypto@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@elastic/request-crypto/-/request-crypto-1.1.2.tgz#2e323550f546f6286994126d462a9ea480a3bfb1" + integrity sha512-i73wjj1Qi8dGJIy170Z8xyJ760mFNjTbdmcp/nEczqWD0miNW6I5wZ5MNrv7M6CXn2m1wMXiT6qzDYd93Hv1Dw== dependencies: - "@elastic/node-crypto" "^0.1.2" + "@elastic/node-crypto" "1.1.1" "@types/node-jose" "1.1.0" node-jose "1.1.0"